diff --git a/.ddev/addon-metadata/redis/manifest.yaml b/.ddev/addon-metadata/redis/manifest.yaml new file mode 100644 index 00000000000..0debc823251 --- /dev/null +++ b/.ddev/addon-metadata/redis/manifest.yaml @@ -0,0 +1,38 @@ +name: redis +repository: ddev/ddev-redis +version: v2.2.0 +install_date: "2026-07-04T11:24:16-04:00" +project_files: + - docker-compose.redis.yaml + - redis/scripts/settings.ddev.redis.php + - redis/scripts/setup-drupal-settings.sh + - redis/scripts/setup-redis-optimized-config.sh + - redis/redis.conf + - redis/advanced.conf + - redis/append.conf + - redis/general.conf + - redis/io.conf + - redis/memory.conf + - redis/network.conf + - redis/security.conf + - redis/snapshots.conf + - commands/host/redis-backend + - commands/redis/redis-cli + - commands/redis/redis-flush +global_files: [] +removal_actions: + - | + #ddev-description:Remove redis settings if applicable + files=( + "${DDEV_APPROOT}/${DDEV_DOCROOT}/sites/default/settings.ddev.redis.php" + "${DDEV_APPROOT}/.ddev/docker-compose.redis_extra.yaml" + ) + for file in "${files[@]}"; do + if [ -f "$file" ]; then + if grep -q '#ddev-generated' "$file"; then + rm -f "$file" + else + echo "Unwilling to remove '$file' because it does not have #ddev-generated in it; you can manually delete it if it is safe to delete." + fi + fi + done diff --git a/.ddev/commands/host/redis-backend b/.ddev/commands/host/redis-backend new file mode 100755 index 00000000000..fbcaba553b8 --- /dev/null +++ b/.ddev/commands/host/redis-backend @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +#ddev-generated + +## Description: Use a different key-value store for Redis +## Usage: redis-backend [optimize] +## Example: ddev redis-backend redis-alpine optimize + +REDIS_DOCKER_IMAGE=${1:-} +REDIS_CONFIG=${2:-} +NAME=$REDIS_DOCKER_IMAGE + +function show_help() { + cat < [optimize] + +Choose from predefined aliases, or provide any Redis-compatible Docker image. +Note that not every Docker image can work right away, and you may need to override +the "command:" in the docker-compose.redis_extra.yaml file + +Available aliases: + redis redis:7 + redis-alpine redis:7-alpine + valkey valkey/valkey:8 + valkey-alpine valkey/valkey:8-alpine + +Custom backend: + You can specify any Docker image, e.g.: + ddev redis-backend redis:6 + +Optional: + optimize Apply additional Redis configuration with resource limits + optimized Same as optimize + +Examples: + ddev redis-backend redis-alpine optimize + ddev redis-backend valkey + ddev redis-backend redis:7.2-alpine +EOF + exit 0 +} + +function optimize_config() { + [[ "$REDIS_CONFIG" != "optimized" && "$REDIS_CONFIG" != "optimize" ]] && return + ddev dotenv set .ddev/.env.redis --redis-optimized=true +} + +function change_hostname() { + [[ "${REDIS_HOSTNAME:-}" == "" ]] && return + ddev dotenv set .ddev/.env.redis --redis-hostname="$REDIS_HOSTNAME" +} + +function cleanup() { + rm -f "$DDEV_APPROOT/.ddev/.env.redis" + rm -rf "$DDEV_APPROOT/.ddev/redis/" + rm -f "$DDEV_APPROOT/.ddev/docker-compose.redis.yaml" "$DDEV_APPROOT/.ddev/docker-compose.redis_extra.yaml" + + redis_volume="ddev-$(ddev status -j | docker run -i --rm ddev/ddev-utilities jq -r '.raw.name')_redis" + if docker volume ls -q | grep -qw "$redis_volume"; then + ddev stop + docker volume rm "$redis_volume" + fi +} + +function check_docker_image() { + echo "Pulling ${REDIS_DOCKER_IMAGE}..." + if ! docker pull "$REDIS_DOCKER_IMAGE"; then + echo >&2 "❌ Unable to pull ${REDIS_DOCKER_IMAGE}" + exit 2 + fi +} + +function use_docker_image() { + [[ "$REDIS_DOCKER_IMAGE" != "redis:7" ]] && ddev dotenv set .ddev/.env.redis --redis-docker-image="$REDIS_DOCKER_IMAGE" + REPO=$(ddev add-on list --installed -j 2>/dev/null | docker run -i --rm ddev/ddev-utilities jq -r '.raw[] | select(.Name=="redis") | .Repository // empty' 2>/dev/null) + ddev add-on get "${REPO:-ddev/ddev-redis}" +} + +case "$REDIS_DOCKER_IMAGE" in + redis) + NAME="Redis 7" + REDIS_DOCKER_IMAGE="redis:7" + ;; + redis-alpine) + NAME="Redis 7 Alpine" + REDIS_DOCKER_IMAGE="redis:7-alpine" + ;; + valkey) + NAME="Valkey 8" + REDIS_DOCKER_IMAGE="valkey/valkey:8" + REDIS_HOSTNAME="valkey" + ;; + valkey-alpine) + NAME="Valkey 8 Alpine" + REDIS_DOCKER_IMAGE="valkey/valkey:8-alpine" + REDIS_HOSTNAME="valkey" + ;; + ""|--help|-h) + show_help + ;; + *) + NAME="$REDIS_DOCKER_IMAGE" + # Allow unknown image, nothing to override + ;; +esac + +check_docker_image +cleanup +optimize_config +change_hostname +use_docker_image + +echo +echo "✅ Redis backend: $REDIS_DOCKER_IMAGE" +if [[ "$REDIS_CONFIG" == "optimized" || "$REDIS_CONFIG" == "optimize" ]]; then + echo "⚙️ Redis config: optimized" +else + echo "⚙️ Redis config: default" +fi + +echo +echo "📝 Commit the '.ddev' directory to version control" + +echo +echo "🔄 Redis config available after 'ddev restart'" diff --git a/.ddev/commands/redis/redis-cli b/.ddev/commands/redis/redis-cli new file mode 100755 index 00000000000..2800343ed53 --- /dev/null +++ b/.ddev/commands/redis/redis-cli @@ -0,0 +1,13 @@ +#!/usr/bin/env sh + +#ddev-generated +## Description: Run redis-cli inside the Redis container +## Usage: redis-cli [flags] [args] +## Example: "ddev redis-cli KEYS *" or "ddev redis-cli INFO" or "ddev redis-cli --version" +## Aliases: redis + +if [ -f /etc/redis/conf/security.conf ]; then + redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" -a redis --no-auth-warning $@ +else + redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" $@ +fi diff --git a/.ddev/commands/redis/redis-flush b/.ddev/commands/redis/redis-flush new file mode 100755 index 00000000000..db90558a7f2 --- /dev/null +++ b/.ddev/commands/redis/redis-flush @@ -0,0 +1,12 @@ +#!/usr/bin/env sh + +#ddev-generated +## Description: Flush all cache inside the Redis container +## Usage: redis-flush +## Example: "ddev redis-flush" + +if [ -f /etc/redis/conf/security.conf ]; then + redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" -a redis --no-auth-warning FLUSHALL ASYNC +else + redis-cli -p 6379 -h "${REDIS_HOSTNAME:-redis}" FLUSHALL ASYNC +fi diff --git a/.ddev/config.yaml b/.ddev/config.yaml new file mode 100644 index 00000000000..8ae8ac62f10 --- /dev/null +++ b/.ddev/config.yaml @@ -0,0 +1,75 @@ +name: convoy +type: laravel +docroot: public +php_version: "8.4" +webserver_type: nginx-fpm + +database: + type: postgres + version: "17" + +# Without this DDEV assigns a random ephemeral host port on every start, which +# breaks saved connections in GUI clients (TablePlus, DataGrip, psql aliases). +host_db_port: "5432" + +nodejs_version: "22" +corepack_enable: false + +# ext-gmp is required by composer.json (prod Dockerfile installs it too). +webimage_extra_packages: + - php8.4-gmp + +# Postgres + redis + mail overrides. These are real container env vars, so they +# take precedence over .env (Laravel's Dotenv does not overwrite existing env). +web_environment: + - APP_URL=https://convoy.ddev.site + - DB_CONNECTION=pgsql + - DB_HOST=db + - DB_PORT=5432 + - DB_DATABASE=db + - DB_TEST_DATABASE=db_test + - DB_USERNAME=db + - DB_PASSWORD=db + - REDIS_HOST=redis + - REDIS_PORT=6379 + - REDIS_PASSWORD= + - CACHE_STORE=redis + - QUEUE_CONNECTION=redis + - SESSION_DRIVER=redis + - MAIL_MAILER=smtp + - MAIL_HOST=localhost + - MAIL_PORT=1025 + +# The test suite (RefreshDatabase) runs against a separate `db_test` database so +# its migrate:fresh / sequence churn never touches dev data. Postgres has no +# CREATE DATABASE IF NOT EXISTS, so createdb is guarded to stay idempotent. +hooks: + post-start: + # Pin `db` in /etc/hosts to the real db container. Some Docker-sandbox setups + # give the web container a resolver with a search domain + ndots:0, so a bare + # `db` lookup can fall through to the sandbox host's wildcard DNS (which answers + # `db..docker.internal` with an unrelated host-network Postgres) — and + # then PHP-FPM and `ddev exec` end up on DIFFERENT databases with the same + # DB_HOST (see docs/v5-next-handoff.md). This fix is sandbox-agnostic: `getent + # hosts db` gets the real container IP from docker's embedded DNS (authoritative + # for the service name), and pinning it in /etc/hosts makes nsswitch `files` + # win over DNS, closing the hole. A no-op where there's no collision. Re-run + # every start so it survives the container IP drifting. + - exec: "sudo bash -c 'H=$(getent hosts db | head -n1 | sed \"s/[[:space:]].*//\"); grep -qw db /etc/hosts || echo \"$H db\" >> /etc/hosts'" + - exec: "PGPASSWORD=db createdb -h db -U db db_test 2>/dev/null || true" + +# Replaces the compose `horizon` and `scheduler` services. +web_extra_daemons: + - name: horizon + command: "php artisan horizon" + directory: /var/www/html + - name: scheduler + command: "php artisan schedule:work" + directory: /var/www/html + +# Expose the Vite dev server. +web_extra_exposed_ports: + - name: vite + container_port: 3000 + http_port: 3011 + https_port: 3000 diff --git a/.ddev/docker-compose.redis.yaml b/.ddev/docker-compose.redis.yaml new file mode 100644 index 00000000000..e9da4c6e48a --- /dev/null +++ b/.ddev/docker-compose.redis.yaml @@ -0,0 +1,27 @@ +#ddev-generated +services: + redis: + container_name: ddev-${DDEV_SITENAME}-redis + image: ${REDIS_DOCKER_IMAGE:-redis:7} + hostname: ${REDIS_HOSTNAME:-redis} + # These labels ensure this service is discoverable by ddev. + labels: + com.ddev.site-name: ${DDEV_SITENAME} + com.ddev.approot: ${DDEV_APPROOT} + restart: "no" + expose: + - 6379 + volumes: + - ".:/mnt/ddev_config" + - "ddev-global-cache:/mnt/ddev-global-cache" + - "./redis:/etc/redis/conf" + - "redis:/data" + command: /etc/redis/conf/redis.conf + x-ddev: + describe-url-port: | + Backend: ${REDIS_DOCKER_IMAGE:-redis:7} + describe-info: | + Pass: + +volumes: + redis: diff --git a/.ddev/docker-compose.victoriametrics.yaml b/.ddev/docker-compose.victoriametrics.yaml new file mode 100644 index 00000000000..ef9bed1d892 --- /dev/null +++ b/.ddev/docker-compose.victoriametrics.yaml @@ -0,0 +1,23 @@ +services: + victoriametrics: + container_name: ddev-${DDEV_SITENAME}-victoriametrics + image: victoriametrics/victoria-metrics:v1.115.0 + hostname: victoriametrics + # These labels ensure this service is discoverable by ddev. + labels: + com.ddev.site-name: ${DDEV_SITENAME} + com.ddev.approot: ${DDEV_APPROOT} + restart: "no" + expose: + - 8428 + command: + - "-retentionPeriod=90d" + - "-storageDataPath=/victoria-metrics-data" + volumes: + - "victoriametrics:/victoria-metrics-data" + x-ddev: + describe-info: | + VictoriaMetrics: http://victoriametrics:8428 + +volumes: + victoriametrics: diff --git a/.ddev/redis/redis.conf b/.ddev/redis/redis.conf new file mode 100644 index 00000000000..937c4e5d34e --- /dev/null +++ b/.ddev/redis/redis.conf @@ -0,0 +1,13 @@ +# Redis configuration. +# #ddev-generated +# Example configuration files for reference: +# http://download.redis.io/redis-stable/redis.conf +# http://download.redis.io/redis-stable/sentinel.conf + +maxmemory 2048mb +maxmemory-policy allkeys-lfu + +# to disable Redis persistence, remove ddev-generated from this file, +# and uncomment the two lines below: +#appendonly no +#save "" diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000000..99c34230cb8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,62 @@ +# Build context excludes. Keep this tight: the image build copies the whole +# tree, and docs/pve-api alone is tens of megabytes of generated API reference +# that has no business in a runtime image. + +.git +.github +.ddev +.idea +.vscode +.claude +.sbx +.tanstack +.tinker + +# Installed fresh inside the build so the image never inherits a host-built tree. +node_modules +vendor + +# Generated during the build (and gitignored), never copied in. +public/build +public/hot +public/storage +resources/scripts/wayfinder +resources/scripts/routeTree.gen.ts +resources/scripts/types/generated.d.ts +resources/scripts/types/typescript-transformer-manifest.json + +# Local state that must not leak into a distributed image. +.env +.env.backup +.env.ci +storage/logs/* +storage/framework/cache/data/* +storage/framework/sessions/* +storage/framework/views/* +storage/*.key + +# Development-only tooling and docs. +tests +docs +phpunit.xml +phpstan.neon +pint.json +.phpunit.cache +.phpunit.result.cache +.styleci.yml +stats.html +CODE_OF_CONDUCT.md +CONTRIBUTOR_LICENSE_AGREEMENT +CHANGELOG.md +AGENTS.md +CLAUDE.md + +# The deployment tooling itself is delivered next to the compose file on the +# host, not baked into the image -- except docker/entrypoint.d, copied explicitly. +docker/install.sh +docker/convoyctl + +**/.DS_Store +**/._.DS_Store +*.tmp.mjs +*.tmp.php diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 98a71192c48..00000000000 --- a/.editorconfig +++ /dev/null @@ -1,818 +0,0 @@ -[*] -charset = utf-8 -end_of_line = lf -indent_size = 4 -indent_style = space -insert_final_newline = false -max_line_length = 120 -tab_width = 4 -ij_continuation_indent_size = 8 -ij_formatter_off_tag = @formatter:off -ij_formatter_on_tag = @formatter:on -ij_formatter_tags_enabled = true -ij_smart_tabs = false -ij_visual_guides = -ij_wrap_on_typing = false - -[*.blade.php] -ij_blade_keep_indents_on_empty_lines = false - -[*.css] -ij_css_align_closing_brace_with_properties = false -ij_css_blank_lines_around_nested_selector = 1 -ij_css_blank_lines_between_blocks = 1 -ij_css_block_comment_add_space = false -ij_css_brace_placement = end_of_line -ij_css_enforce_quotes_on_format = false -ij_css_hex_color_long_format = false -ij_css_hex_color_lower_case = false -ij_css_hex_color_short_format = false -ij_css_hex_color_upper_case = false -ij_css_keep_blank_lines_in_code = 2 -ij_css_keep_indents_on_empty_lines = false -ij_css_keep_single_line_blocks = false -ij_css_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow -ij_css_space_after_colon = true -ij_css_space_before_opening_brace = true -ij_css_use_double_quotes = true -ij_css_value_alignment = do_not_align - -[*.feature] -indent_size = 2 -ij_gherkin_keep_indents_on_empty_lines = false - -[*.less] -indent_size = 2 -ij_less_align_closing_brace_with_properties = false -ij_less_blank_lines_around_nested_selector = 1 -ij_less_blank_lines_between_blocks = 1 -ij_less_block_comment_add_space = false -ij_less_brace_placement = 0 -ij_less_enforce_quotes_on_format = false -ij_less_hex_color_long_format = false -ij_less_hex_color_lower_case = false -ij_less_hex_color_short_format = false -ij_less_hex_color_upper_case = false -ij_less_keep_blank_lines_in_code = 2 -ij_less_keep_indents_on_empty_lines = false -ij_less_keep_single_line_blocks = false -ij_less_line_comment_add_space = false -ij_less_line_comment_at_first_column = false -ij_less_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow -ij_less_space_after_colon = true -ij_less_space_before_opening_brace = true -ij_less_use_double_quotes = true -ij_less_value_alignment = 0 - -[*.sass] -indent_size = 2 -ij_sass_align_closing_brace_with_properties = false -ij_sass_blank_lines_around_nested_selector = 1 -ij_sass_blank_lines_between_blocks = 1 -ij_sass_brace_placement = 0 -ij_sass_enforce_quotes_on_format = false -ij_sass_hex_color_long_format = false -ij_sass_hex_color_lower_case = false -ij_sass_hex_color_short_format = false -ij_sass_hex_color_upper_case = false -ij_sass_keep_blank_lines_in_code = 2 -ij_sass_keep_indents_on_empty_lines = false -ij_sass_keep_single_line_blocks = false -ij_sass_line_comment_add_space = false -ij_sass_line_comment_at_first_column = false -ij_sass_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow -ij_sass_space_after_colon = true -ij_sass_space_before_opening_brace = true -ij_sass_use_double_quotes = true -ij_sass_value_alignment = 0 - -[*.scss] -indent_size = 2 -ij_scss_align_closing_brace_with_properties = false -ij_scss_blank_lines_around_nested_selector = 1 -ij_scss_blank_lines_between_blocks = 1 -ij_scss_block_comment_add_space = false -ij_scss_brace_placement = 0 -ij_scss_enforce_quotes_on_format = false -ij_scss_hex_color_long_format = false -ij_scss_hex_color_lower_case = false -ij_scss_hex_color_short_format = false -ij_scss_hex_color_upper_case = false -ij_scss_keep_blank_lines_in_code = 2 -ij_scss_keep_indents_on_empty_lines = false -ij_scss_keep_single_line_blocks = false -ij_scss_line_comment_add_space = false -ij_scss_line_comment_at_first_column = false -ij_scss_properties_order = font,font-family,font-size,font-weight,font-style,font-variant,font-size-adjust,font-stretch,line-height,position,z-index,top,right,bottom,left,display,visibility,float,clear,overflow,overflow-x,overflow-y,clip,zoom,align-content,align-items,align-self,flex,flex-flow,flex-basis,flex-direction,flex-grow,flex-shrink,flex-wrap,justify-content,order,box-sizing,width,min-width,max-width,height,min-height,max-height,margin,margin-top,margin-right,margin-bottom,margin-left,padding,padding-top,padding-right,padding-bottom,padding-left,table-layout,empty-cells,caption-side,border-spacing,border-collapse,list-style,list-style-position,list-style-type,list-style-image,content,quotes,counter-reset,counter-increment,resize,cursor,user-select,nav-index,nav-up,nav-right,nav-down,nav-left,transition,transition-delay,transition-timing-function,transition-duration,transition-property,transform,transform-origin,animation,animation-name,animation-duration,animation-play-state,animation-timing-function,animation-delay,animation-iteration-count,animation-direction,text-align,text-align-last,vertical-align,white-space,text-decoration,text-emphasis,text-emphasis-color,text-emphasis-style,text-emphasis-position,text-indent,text-justify,letter-spacing,word-spacing,text-outline,text-transform,text-wrap,text-overflow,text-overflow-ellipsis,text-overflow-mode,word-wrap,word-break,tab-size,hyphens,pointer-events,opacity,color,border,border-width,border-style,border-color,border-top,border-top-width,border-top-style,border-top-color,border-right,border-right-width,border-right-style,border-right-color,border-bottom,border-bottom-width,border-bottom-style,border-bottom-color,border-left,border-left-width,border-left-style,border-left-color,border-radius,border-top-left-radius,border-top-right-radius,border-bottom-right-radius,border-bottom-left-radius,border-image,border-image-source,border-image-slice,border-image-width,border-image-outset,border-image-repeat,outline,outline-width,outline-style,outline-color,outline-offset,background,background-color,background-image,background-repeat,background-attachment,background-position,background-position-x,background-position-y,background-clip,background-origin,background-size,box-decoration-break,box-shadow,text-shadow -ij_scss_space_after_colon = true -ij_scss_space_before_opening_brace = true -ij_scss_use_double_quotes = true -ij_scss_value_alignment = 0 - -[*.twig] -ij_twig_keep_indents_on_empty_lines = false -ij_twig_spaces_inside_comments_delimiters = true -ij_twig_spaces_inside_delimiters = true -ij_twig_spaces_inside_variable_delimiters = true - -[*.vue] -indent_size = 2 -tab_width = 2 -ij_continuation_indent_size = 4 -ij_vue_indent_children_of_top_level = template -ij_vue_interpolation_new_line_after_start_delimiter = true -ij_vue_interpolation_new_line_before_end_delimiter = true -ij_vue_interpolation_wrap = off -ij_vue_keep_indents_on_empty_lines = false -ij_vue_spaces_within_interpolation_expressions = true - -[.editorconfig] -ij_editorconfig_align_group_field_declarations = false -ij_editorconfig_space_after_colon = false -ij_editorconfig_space_after_comma = true -ij_editorconfig_space_before_colon = false -ij_editorconfig_space_before_comma = false -ij_editorconfig_spaces_around_assignment_operators = true - -[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul,phpunit.xml.dist}] -ij_xml_align_attributes = true -ij_xml_align_text = false -ij_xml_attribute_wrap = normal -ij_xml_block_comment_add_space = false -ij_xml_block_comment_at_first_column = true -ij_xml_keep_blank_lines = 2 -ij_xml_keep_indents_on_empty_lines = false -ij_xml_keep_line_breaks = true -ij_xml_keep_line_breaks_in_text = true -ij_xml_keep_whitespaces = false -ij_xml_keep_whitespaces_around_cdata = preserve -ij_xml_keep_whitespaces_inside_cdata = false -ij_xml_line_comment_at_first_column = true -ij_xml_space_after_tag_name = false -ij_xml_space_around_equals_in_attribute = false -ij_xml_space_inside_empty_tag = false -ij_xml_text_wrap = normal - -[{*.ats,*.cts,*.mts,*.ts}] -ij_continuation_indent_size = 4 -ij_typescript_align_imports = false -ij_typescript_align_multiline_array_initializer_expression = false -ij_typescript_align_multiline_binary_operation = false -ij_typescript_align_multiline_chained_methods = false -ij_typescript_align_multiline_extends_list = false -ij_typescript_align_multiline_for = true -ij_typescript_align_multiline_parameters = true -ij_typescript_align_multiline_parameters_in_calls = false -ij_typescript_align_multiline_ternary_operation = false -ij_typescript_align_object_properties = 0 -ij_typescript_align_union_types = false -ij_typescript_align_var_statements = 0 -ij_typescript_array_initializer_new_line_after_left_brace = false -ij_typescript_array_initializer_right_brace_on_new_line = false -ij_typescript_array_initializer_wrap = off -ij_typescript_assignment_wrap = off -ij_typescript_binary_operation_sign_on_next_line = false -ij_typescript_binary_operation_wrap = off -ij_typescript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** -ij_typescript_blank_lines_after_imports = 1 -ij_typescript_blank_lines_around_class = 1 -ij_typescript_blank_lines_around_field = 0 -ij_typescript_blank_lines_around_field_in_interface = 0 -ij_typescript_blank_lines_around_function = 1 -ij_typescript_blank_lines_around_method = 1 -ij_typescript_blank_lines_around_method_in_interface = 1 -ij_typescript_block_brace_style = end_of_line -ij_typescript_block_comment_add_space = false -ij_typescript_block_comment_at_first_column = true -ij_typescript_call_parameters_new_line_after_left_paren = false -ij_typescript_call_parameters_right_paren_on_new_line = false -ij_typescript_call_parameters_wrap = off -ij_typescript_catch_on_new_line = false -ij_typescript_chained_call_dot_on_new_line = true -ij_typescript_class_brace_style = end_of_line -ij_typescript_comma_on_new_line = false -ij_typescript_do_while_brace_force = never -ij_typescript_else_on_new_line = false -ij_typescript_enforce_trailing_comma = keep -ij_typescript_enum_constants_wrap = on_every_item -ij_typescript_extends_keyword_wrap = off -ij_typescript_extends_list_wrap = off -ij_typescript_field_prefix = _ -ij_typescript_file_name_style = relaxed -ij_typescript_finally_on_new_line = false -ij_typescript_for_brace_force = never -ij_typescript_for_statement_new_line_after_left_paren = false -ij_typescript_for_statement_right_paren_on_new_line = false -ij_typescript_for_statement_wrap = off -ij_typescript_force_quote_style = false -ij_typescript_force_semicolon_style = false -ij_typescript_function_expression_brace_style = end_of_line -ij_typescript_if_brace_force = never -ij_typescript_import_merge_members = global -ij_typescript_import_prefer_absolute_path = global -ij_typescript_import_sort_members = true -ij_typescript_import_sort_module_name = false -ij_typescript_import_use_node_resolution = true -ij_typescript_imports_wrap = on_every_item -ij_typescript_indent_case_from_switch = true -ij_typescript_indent_chained_calls = true -ij_typescript_indent_package_children = 0 -ij_typescript_jsdoc_include_types = false -ij_typescript_jsx_attribute_value = braces -ij_typescript_keep_blank_lines_in_code = 2 -ij_typescript_keep_first_column_comment = true -ij_typescript_keep_indents_on_empty_lines = false -ij_typescript_keep_line_breaks = true -ij_typescript_keep_simple_blocks_in_one_line = false -ij_typescript_keep_simple_methods_in_one_line = false -ij_typescript_line_comment_add_space = true -ij_typescript_line_comment_at_first_column = false -ij_typescript_method_brace_style = end_of_line -ij_typescript_method_call_chain_wrap = off -ij_typescript_method_parameters_new_line_after_left_paren = false -ij_typescript_method_parameters_right_paren_on_new_line = false -ij_typescript_method_parameters_wrap = off -ij_typescript_object_literal_wrap = on_every_item -ij_typescript_object_types_wrap = on_every_item -ij_typescript_parentheses_expression_new_line_after_left_paren = false -ij_typescript_parentheses_expression_right_paren_on_new_line = false -ij_typescript_place_assignment_sign_on_next_line = false -ij_typescript_prefer_as_type_cast = false -ij_typescript_prefer_explicit_types_function_expression_returns = false -ij_typescript_prefer_explicit_types_function_returns = false -ij_typescript_prefer_explicit_types_vars_fields = false -ij_typescript_prefer_parameters_wrap = false -ij_typescript_property_prefix = -ij_typescript_reformat_c_style_comments = false -ij_typescript_space_after_colon = true -ij_typescript_space_after_comma = true -ij_typescript_space_after_dots_in_rest_parameter = false -ij_typescript_space_after_generator_mult = true -ij_typescript_space_after_property_colon = true -ij_typescript_space_after_quest = true -ij_typescript_space_after_type_colon = true -ij_typescript_space_after_unary_not = false -ij_typescript_space_before_async_arrow_lparen = true -ij_typescript_space_before_catch_keyword = true -ij_typescript_space_before_catch_left_brace = true -ij_typescript_space_before_catch_parentheses = true -ij_typescript_space_before_class_lbrace = true -ij_typescript_space_before_class_left_brace = true -ij_typescript_space_before_colon = true -ij_typescript_space_before_comma = false -ij_typescript_space_before_do_left_brace = true -ij_typescript_space_before_else_keyword = true -ij_typescript_space_before_else_left_brace = true -ij_typescript_space_before_finally_keyword = true -ij_typescript_space_before_finally_left_brace = true -ij_typescript_space_before_for_left_brace = true -ij_typescript_space_before_for_parentheses = true -ij_typescript_space_before_for_semicolon = false -ij_typescript_space_before_function_left_parenth = true -ij_typescript_space_before_generator_mult = false -ij_typescript_space_before_if_left_brace = true -ij_typescript_space_before_if_parentheses = true -ij_typescript_space_before_method_call_parentheses = false -ij_typescript_space_before_method_left_brace = true -ij_typescript_space_before_method_parentheses = false -ij_typescript_space_before_property_colon = false -ij_typescript_space_before_quest = true -ij_typescript_space_before_switch_left_brace = true -ij_typescript_space_before_switch_parentheses = true -ij_typescript_space_before_try_left_brace = true -ij_typescript_space_before_type_colon = false -ij_typescript_space_before_unary_not = false -ij_typescript_space_before_while_keyword = true -ij_typescript_space_before_while_left_brace = true -ij_typescript_space_before_while_parentheses = true -ij_typescript_spaces_around_additive_operators = true -ij_typescript_spaces_around_arrow_function_operator = true -ij_typescript_spaces_around_assignment_operators = true -ij_typescript_spaces_around_bitwise_operators = true -ij_typescript_spaces_around_equality_operators = true -ij_typescript_spaces_around_logical_operators = true -ij_typescript_spaces_around_multiplicative_operators = true -ij_typescript_spaces_around_relational_operators = true -ij_typescript_spaces_around_shift_operators = true -ij_typescript_spaces_around_unary_operator = false -ij_typescript_spaces_within_array_initializer_brackets = false -ij_typescript_spaces_within_brackets = false -ij_typescript_spaces_within_catch_parentheses = false -ij_typescript_spaces_within_for_parentheses = false -ij_typescript_spaces_within_if_parentheses = false -ij_typescript_spaces_within_imports = false -ij_typescript_spaces_within_interpolation_expressions = false -ij_typescript_spaces_within_method_call_parentheses = false -ij_typescript_spaces_within_method_parentheses = false -ij_typescript_spaces_within_object_literal_braces = false -ij_typescript_spaces_within_object_type_braces = true -ij_typescript_spaces_within_parentheses = false -ij_typescript_spaces_within_switch_parentheses = false -ij_typescript_spaces_within_type_assertion = false -ij_typescript_spaces_within_union_types = true -ij_typescript_spaces_within_while_parentheses = false -ij_typescript_special_else_if_treatment = true -ij_typescript_ternary_operation_signs_on_next_line = false -ij_typescript_ternary_operation_wrap = off -ij_typescript_union_types_wrap = on_every_item -ij_typescript_use_chained_calls_group_indents = false -ij_typescript_use_double_quotes = true -ij_typescript_use_explicit_js_extension = auto -ij_typescript_use_path_mapping = always -ij_typescript_use_public_modifier = false -ij_typescript_use_semicolon_after_statement = true -ij_typescript_var_declaration_wrap = normal -ij_typescript_while_brace_force = never -ij_typescript_while_on_new_line = false -ij_typescript_wrap_comments = false - -[{*.bash,*.sh,*.zsh}] -indent_size = 2 -tab_width = 2 -ij_shell_binary_ops_start_line = false -ij_shell_keep_column_alignment_padding = false -ij_shell_minify_program = false -ij_shell_redirect_followed_by_space = false -ij_shell_switch_cases_indented = false -ij_shell_use_unix_line_separator = true - -[{*.cjs,*.js}] -ij_continuation_indent_size = 4 -ij_javascript_align_imports = false -ij_javascript_align_multiline_array_initializer_expression = false -ij_javascript_align_multiline_binary_operation = false -ij_javascript_align_multiline_chained_methods = false -ij_javascript_align_multiline_extends_list = false -ij_javascript_align_multiline_for = true -ij_javascript_align_multiline_parameters = true -ij_javascript_align_multiline_parameters_in_calls = false -ij_javascript_align_multiline_ternary_operation = false -ij_javascript_align_object_properties = 0 -ij_javascript_align_union_types = false -ij_javascript_align_var_statements = 0 -ij_javascript_array_initializer_new_line_after_left_brace = false -ij_javascript_array_initializer_right_brace_on_new_line = false -ij_javascript_array_initializer_wrap = off -ij_javascript_assignment_wrap = off -ij_javascript_binary_operation_sign_on_next_line = false -ij_javascript_binary_operation_wrap = off -ij_javascript_blacklist_imports = rxjs/Rx,node_modules/**,**/node_modules/**,@angular/material,@angular/material/typings/** -ij_javascript_blank_lines_after_imports = 1 -ij_javascript_blank_lines_around_class = 1 -ij_javascript_blank_lines_around_field = 0 -ij_javascript_blank_lines_around_function = 1 -ij_javascript_blank_lines_around_method = 1 -ij_javascript_block_brace_style = end_of_line -ij_javascript_block_comment_add_space = false -ij_javascript_block_comment_at_first_column = true -ij_javascript_call_parameters_new_line_after_left_paren = false -ij_javascript_call_parameters_right_paren_on_new_line = false -ij_javascript_call_parameters_wrap = off -ij_javascript_catch_on_new_line = false -ij_javascript_chained_call_dot_on_new_line = true -ij_javascript_class_brace_style = end_of_line -ij_javascript_comma_on_new_line = false -ij_javascript_do_while_brace_force = never -ij_javascript_else_on_new_line = false -ij_javascript_enforce_trailing_comma = keep -ij_javascript_extends_keyword_wrap = off -ij_javascript_extends_list_wrap = off -ij_javascript_field_prefix = _ -ij_javascript_file_name_style = relaxed -ij_javascript_finally_on_new_line = false -ij_javascript_for_brace_force = never -ij_javascript_for_statement_new_line_after_left_paren = false -ij_javascript_for_statement_right_paren_on_new_line = false -ij_javascript_for_statement_wrap = off -ij_javascript_force_quote_style = false -ij_javascript_force_semicolon_style = false -ij_javascript_function_expression_brace_style = end_of_line -ij_javascript_if_brace_force = never -ij_javascript_import_merge_members = global -ij_javascript_import_prefer_absolute_path = global -ij_javascript_import_sort_members = true -ij_javascript_import_sort_module_name = false -ij_javascript_import_use_node_resolution = true -ij_javascript_imports_wrap = on_every_item -ij_javascript_indent_case_from_switch = true -ij_javascript_indent_chained_calls = true -ij_javascript_indent_package_children = 0 -ij_javascript_jsx_attribute_value = braces -ij_javascript_keep_blank_lines_in_code = 2 -ij_javascript_keep_first_column_comment = true -ij_javascript_keep_indents_on_empty_lines = false -ij_javascript_keep_line_breaks = true -ij_javascript_keep_simple_blocks_in_one_line = false -ij_javascript_keep_simple_methods_in_one_line = false -ij_javascript_line_comment_add_space = true -ij_javascript_line_comment_at_first_column = false -ij_javascript_method_brace_style = end_of_line -ij_javascript_method_call_chain_wrap = off -ij_javascript_method_parameters_new_line_after_left_paren = false -ij_javascript_method_parameters_right_paren_on_new_line = false -ij_javascript_method_parameters_wrap = off -ij_javascript_object_literal_wrap = on_every_item -ij_javascript_object_types_wrap = on_every_item -ij_javascript_parentheses_expression_new_line_after_left_paren = false -ij_javascript_parentheses_expression_right_paren_on_new_line = false -ij_javascript_place_assignment_sign_on_next_line = false -ij_javascript_prefer_as_type_cast = false -ij_javascript_prefer_explicit_types_function_expression_returns = false -ij_javascript_prefer_explicit_types_function_returns = false -ij_javascript_prefer_explicit_types_vars_fields = false -ij_javascript_prefer_parameters_wrap = false -ij_javascript_property_prefix = -ij_javascript_reformat_c_style_comments = false -ij_javascript_space_after_colon = true -ij_javascript_space_after_comma = true -ij_javascript_space_after_dots_in_rest_parameter = false -ij_javascript_space_after_generator_mult = true -ij_javascript_space_after_property_colon = true -ij_javascript_space_after_quest = true -ij_javascript_space_after_type_colon = true -ij_javascript_space_after_unary_not = false -ij_javascript_space_before_async_arrow_lparen = true -ij_javascript_space_before_catch_keyword = true -ij_javascript_space_before_catch_left_brace = true -ij_javascript_space_before_catch_parentheses = true -ij_javascript_space_before_class_lbrace = true -ij_javascript_space_before_class_left_brace = true -ij_javascript_space_before_colon = true -ij_javascript_space_before_comma = false -ij_javascript_space_before_do_left_brace = true -ij_javascript_space_before_else_keyword = true -ij_javascript_space_before_else_left_brace = true -ij_javascript_space_before_finally_keyword = true -ij_javascript_space_before_finally_left_brace = true -ij_javascript_space_before_for_left_brace = true -ij_javascript_space_before_for_parentheses = true -ij_javascript_space_before_for_semicolon = false -ij_javascript_space_before_function_left_parenth = true -ij_javascript_space_before_generator_mult = false -ij_javascript_space_before_if_left_brace = true -ij_javascript_space_before_if_parentheses = true -ij_javascript_space_before_method_call_parentheses = false -ij_javascript_space_before_method_left_brace = true -ij_javascript_space_before_method_parentheses = false -ij_javascript_space_before_property_colon = false -ij_javascript_space_before_quest = true -ij_javascript_space_before_switch_left_brace = true -ij_javascript_space_before_switch_parentheses = true -ij_javascript_space_before_try_left_brace = true -ij_javascript_space_before_type_colon = false -ij_javascript_space_before_unary_not = false -ij_javascript_space_before_while_keyword = true -ij_javascript_space_before_while_left_brace = true -ij_javascript_space_before_while_parentheses = true -ij_javascript_spaces_around_additive_operators = true -ij_javascript_spaces_around_arrow_function_operator = true -ij_javascript_spaces_around_assignment_operators = true -ij_javascript_spaces_around_bitwise_operators = true -ij_javascript_spaces_around_equality_operators = true -ij_javascript_spaces_around_logical_operators = true -ij_javascript_spaces_around_multiplicative_operators = true -ij_javascript_spaces_around_relational_operators = true -ij_javascript_spaces_around_shift_operators = true -ij_javascript_spaces_around_unary_operator = false -ij_javascript_spaces_within_array_initializer_brackets = false -ij_javascript_spaces_within_brackets = false -ij_javascript_spaces_within_catch_parentheses = false -ij_javascript_spaces_within_for_parentheses = false -ij_javascript_spaces_within_if_parentheses = false -ij_javascript_spaces_within_imports = false -ij_javascript_spaces_within_interpolation_expressions = false -ij_javascript_spaces_within_method_call_parentheses = false -ij_javascript_spaces_within_method_parentheses = false -ij_javascript_spaces_within_object_literal_braces = false -ij_javascript_spaces_within_object_type_braces = true -ij_javascript_spaces_within_parentheses = false -ij_javascript_spaces_within_switch_parentheses = false -ij_javascript_spaces_within_type_assertion = false -ij_javascript_spaces_within_union_types = true -ij_javascript_spaces_within_while_parentheses = false -ij_javascript_special_else_if_treatment = true -ij_javascript_ternary_operation_signs_on_next_line = false -ij_javascript_ternary_operation_wrap = off -ij_javascript_union_types_wrap = on_every_item -ij_javascript_use_chained_calls_group_indents = false -ij_javascript_use_double_quotes = true -ij_javascript_use_explicit_js_extension = auto -ij_javascript_use_path_mapping = always -ij_javascript_use_public_modifier = false -ij_javascript_use_semicolon_after_statement = true -ij_javascript_var_declaration_wrap = normal -ij_javascript_while_brace_force = never -ij_javascript_while_on_new_line = false -ij_javascript_wrap_comments = false - -[{*.ctp,*.hphp,*.inc,*.module,*.php,*.php4,*.php5,*.phtml}] -max_line_length = 100 -ij_continuation_indent_size = 4 -ij_php_align_assignments = false -ij_php_align_class_constants = false -ij_php_align_enum_cases = false -ij_php_align_group_field_declarations = false -ij_php_align_inline_comments = false -ij_php_align_key_value_pairs = false -ij_php_align_match_arm_bodies = false -ij_php_align_multiline_array_initializer_expression = false -ij_php_align_multiline_binary_operation = false -ij_php_align_multiline_chained_methods = true -ij_php_align_multiline_extends_list = false -ij_php_align_multiline_for = true -ij_php_align_multiline_parameters = true -ij_php_align_multiline_parameters_in_calls = false -ij_php_align_multiline_ternary_operation = false -ij_php_align_named_arguments = true -ij_php_align_phpdoc_comments = false -ij_php_align_phpdoc_param_names = false -ij_php_anonymous_brace_style = end_of_line -ij_php_api_weight = 28 -ij_php_array_initializer_new_line_after_left_brace = false -ij_php_array_initializer_right_brace_on_new_line = false -ij_php_array_initializer_wrap = off -ij_php_assignment_wrap = off -ij_php_attributes_wrap = off -ij_php_author_weight = 28 -ij_php_binary_operation_sign_on_next_line = false -ij_php_binary_operation_wrap = off -ij_php_blank_lines_after_class_header = 0 -ij_php_blank_lines_after_function = 1 -ij_php_blank_lines_after_imports = 1 -ij_php_blank_lines_after_opening_tag = 0 -ij_php_blank_lines_after_package = 0 -ij_php_blank_lines_around_class = 1 -ij_php_blank_lines_around_constants = 0 -ij_php_blank_lines_around_enum_cases = 0 -ij_php_blank_lines_around_field = 0 -ij_php_blank_lines_around_method = 1 -ij_php_blank_lines_before_class_end = 0 -ij_php_blank_lines_before_imports = 1 -ij_php_blank_lines_before_method_body = 0 -ij_php_blank_lines_before_package = 1 -ij_php_blank_lines_before_return_statement = 0 -ij_php_blank_lines_between_imports = 0 -ij_php_block_brace_style = end_of_line -ij_php_call_parameters_new_line_after_left_paren = true -ij_php_call_parameters_right_paren_on_new_line = true -ij_php_call_parameters_wrap = normal -ij_php_catch_on_new_line = false -ij_php_category_weight = 28 -ij_php_class_brace_style = next_line -ij_php_comma_after_last_argument = true -ij_php_comma_after_last_array_element = true -ij_php_comma_after_last_closure_use_var = true -ij_php_comma_after_last_match_arm = true -ij_php_comma_after_last_parameter = true -ij_php_concat_spaces = true -ij_php_copyright_weight = 28 -ij_php_deprecated_weight = 28 -ij_php_do_while_brace_force = never -ij_php_else_if_style = combine -ij_php_else_on_new_line = false -ij_php_example_weight = 28 -ij_php_extends_keyword_wrap = off -ij_php_extends_list_wrap = off -ij_php_fields_default_visibility = private -ij_php_filesource_weight = 28 -ij_php_finally_on_new_line = false -ij_php_for_brace_force = never -ij_php_for_statement_new_line_after_left_paren = false -ij_php_for_statement_right_paren_on_new_line = false -ij_php_for_statement_wrap = off -ij_php_force_empty_methods_in_one_line = false -ij_php_force_short_declaration_array_style = true -ij_php_getters_setters_naming_style = camel_case -ij_php_getters_setters_order_style = getters_first -ij_php_global_weight = 28 -ij_php_group_use_wrap = on_every_item -ij_php_if_brace_force = never -ij_php_if_lparen_on_next_line = false -ij_php_if_rparen_on_next_line = false -ij_php_ignore_weight = 28 -ij_php_import_sorting = alphabetic -ij_php_indent_break_from_case = true -ij_php_indent_case_from_switch = true -ij_php_indent_code_in_php_tags = false -ij_php_internal_weight = 28 -ij_php_keep_blank_lines_after_lbrace = 2 -ij_php_keep_blank_lines_before_right_brace = 2 -ij_php_keep_blank_lines_in_code = 2 -ij_php_keep_blank_lines_in_declarations = 2 -ij_php_keep_control_statement_in_one_line = true -ij_php_keep_first_column_comment = true -ij_php_keep_indents_on_empty_lines = false -ij_php_keep_line_breaks = true -ij_php_keep_rparen_and_lbrace_on_one_line = false -ij_php_keep_simple_classes_in_one_line = false -ij_php_keep_simple_methods_in_one_line = false -ij_php_lambda_brace_style = end_of_line -ij_php_license_weight = 28 -ij_php_line_comment_add_space = false -ij_php_line_comment_at_first_column = true -ij_php_link_weight = 28 -ij_php_lower_case_boolean_const = true -ij_php_lower_case_keywords = true -ij_php_lower_case_null_const = true -ij_php_method_brace_style = next_line -ij_php_method_call_chain_wrap = normal -ij_php_method_parameters_new_line_after_left_paren = true -ij_php_method_parameters_right_paren_on_new_line = true -ij_php_method_parameters_wrap = normal -ij_php_method_weight = 28 -ij_php_modifier_list_wrap = false -ij_php_multiline_chained_calls_semicolon_on_new_line = false -ij_php_namespace_brace_style = 1 -ij_php_new_line_after_php_opening_tag = true -ij_php_null_type_position = in_the_end -ij_php_package_weight = 28 -ij_php_param_weight = 0 -ij_php_parameters_attributes_wrap = off -ij_php_parentheses_expression_new_line_after_left_paren = false -ij_php_parentheses_expression_right_paren_on_new_line = false -ij_php_phpdoc_blank_line_before_tags = false -ij_php_phpdoc_blank_lines_around_parameters = false -ij_php_phpdoc_keep_blank_lines = true -ij_php_phpdoc_param_spaces_between_name_and_description = 1 -ij_php_phpdoc_param_spaces_between_tag_and_type = 1 -ij_php_phpdoc_param_spaces_between_type_and_name = 1 -ij_php_phpdoc_use_fqcn = false -ij_php_phpdoc_wrap_long_lines = false -ij_php_place_assignment_sign_on_next_line = false -ij_php_place_parens_for_constructor = 1 -ij_php_property_read_weight = 28 -ij_php_property_weight = 28 -ij_php_property_write_weight = 28 -ij_php_return_type_on_new_line = false -ij_php_return_weight = 1 -ij_php_see_weight = 28 -ij_php_since_weight = 28 -ij_php_sort_phpdoc_elements = true -ij_php_space_after_colon = true -ij_php_space_after_colon_in_enum_backed_type = true -ij_php_space_after_colon_in_named_argument = true -ij_php_space_after_colon_in_return_type = true -ij_php_space_after_comma = true -ij_php_space_after_for_semicolon = true -ij_php_space_after_quest = true -ij_php_space_after_type_cast = false -ij_php_space_after_unary_not = false -ij_php_space_before_array_initializer_left_brace = false -ij_php_space_before_catch_keyword = true -ij_php_space_before_catch_left_brace = true -ij_php_space_before_catch_parentheses = true -ij_php_space_before_class_left_brace = true -ij_php_space_before_closure_left_parenthesis = true -ij_php_space_before_colon = true -ij_php_space_before_colon_in_enum_backed_type = false -ij_php_space_before_colon_in_named_argument = false -ij_php_space_before_colon_in_return_type = false -ij_php_space_before_comma = false -ij_php_space_before_do_left_brace = true -ij_php_space_before_else_keyword = true -ij_php_space_before_else_left_brace = true -ij_php_space_before_finally_keyword = true -ij_php_space_before_finally_left_brace = true -ij_php_space_before_for_left_brace = true -ij_php_space_before_for_parentheses = true -ij_php_space_before_for_semicolon = false -ij_php_space_before_if_left_brace = true -ij_php_space_before_if_parentheses = true -ij_php_space_before_method_call_parentheses = false -ij_php_space_before_method_left_brace = true -ij_php_space_before_method_parentheses = false -ij_php_space_before_quest = true -ij_php_space_before_short_closure_left_parenthesis = true -ij_php_space_before_switch_left_brace = true -ij_php_space_before_switch_parentheses = true -ij_php_space_before_try_left_brace = true -ij_php_space_before_unary_not = false -ij_php_space_before_while_keyword = true -ij_php_space_before_while_left_brace = true -ij_php_space_before_while_parentheses = true -ij_php_space_between_ternary_quest_and_colon = false -ij_php_spaces_around_additive_operators = true -ij_php_spaces_around_arrow = false -ij_php_spaces_around_assignment_in_declare = false -ij_php_spaces_around_assignment_operators = true -ij_php_spaces_around_bitwise_operators = true -ij_php_spaces_around_equality_operators = true -ij_php_spaces_around_logical_operators = true -ij_php_spaces_around_multiplicative_operators = true -ij_php_spaces_around_null_coalesce_operator = true -ij_php_spaces_around_pipe_in_union_type = false -ij_php_spaces_around_relational_operators = true -ij_php_spaces_around_shift_operators = true -ij_php_spaces_around_unary_operator = false -ij_php_spaces_around_var_within_brackets = false -ij_php_spaces_within_array_initializer_braces = false -ij_php_spaces_within_brackets = false -ij_php_spaces_within_catch_parentheses = false -ij_php_spaces_within_for_parentheses = false -ij_php_spaces_within_if_parentheses = false -ij_php_spaces_within_method_call_parentheses = false -ij_php_spaces_within_method_parentheses = false -ij_php_spaces_within_parentheses = false -ij_php_spaces_within_short_echo_tags = true -ij_php_spaces_within_switch_parentheses = false -ij_php_spaces_within_while_parentheses = false -ij_php_special_else_if_treatment = false -ij_php_subpackage_weight = 28 -ij_php_ternary_operation_signs_on_next_line = false -ij_php_ternary_operation_wrap = off -ij_php_throws_weight = 2 -ij_php_todo_weight = 28 -ij_php_treat_multiline_arrays_and_lambdas_multiline = false -ij_php_unknown_tag_weight = 28 -ij_php_upper_case_boolean_const = false -ij_php_upper_case_null_const = false -ij_php_uses_weight = 28 -ij_php_var_weight = 28 -ij_php_variable_naming_style = mixed -ij_php_version_weight = 28 -ij_php_while_brace_force = never -ij_php_while_on_new_line = false - -[{*.har,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.prettierrc,.stylelintrc,bowerrc,composer.lock,jest.config}] -indent_size = 2 -ij_json_array_wrapping = split_into_lines -ij_json_keep_blank_lines_in_code = 0 -ij_json_keep_indents_on_empty_lines = false -ij_json_keep_line_breaks = true -ij_json_keep_trailing_comma = false -ij_json_object_wrapping = split_into_lines -ij_json_property_alignment = do_not_align -ij_json_space_after_colon = true -ij_json_space_after_comma = true -ij_json_space_before_colon = false -ij_json_space_before_comma = false -ij_json_spaces_within_braces = false -ij_json_spaces_within_brackets = false -ij_json_wrap_long_lines = false - -[{*.htm,*.html,*.ng,*.sht,*.shtm,*.shtml}] -ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 -ij_html_align_attributes = true -ij_html_align_text = false -ij_html_attribute_wrap = normal -ij_html_block_comment_add_space = false -ij_html_block_comment_at_first_column = true -ij_html_do_not_align_children_of_min_lines = 0 -ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p -ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot -ij_html_enforce_quotes = false -ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var -ij_html_keep_blank_lines = 2 -ij_html_keep_indents_on_empty_lines = false -ij_html_keep_line_breaks = true -ij_html_keep_line_breaks_in_text = true -ij_html_keep_whitespaces = false -ij_html_keep_whitespaces_inside = span,pre,textarea -ij_html_line_comment_at_first_column = true -ij_html_new_line_after_last_attribute = never -ij_html_new_line_before_first_attribute = never -ij_html_quote_style = double -ij_html_remove_new_line_before_tags = br -ij_html_space_after_tag_name = false -ij_html_space_around_equality_in_attribute = false -ij_html_space_inside_empty_tag = false -ij_html_text_wrap = normal - -[{*.http,*.rest}] -indent_size = 0 -ij_continuation_indent_size = 4 -ij_http-request_call_parameters_wrap = normal -ij_http-request_method_parameters_wrap = split_into_lines -ij_http-request_space_before_comma = true -ij_http-request_spaces_around_assignment_operators = true - -[{*.markdown,*.md}] -ij_markdown_force_one_space_after_blockquote_symbol = true -ij_markdown_force_one_space_after_header_symbol = true -ij_markdown_force_one_space_after_list_bullet = true -ij_markdown_force_one_space_between_words = true -ij_markdown_format_tables = true -ij_markdown_insert_quote_arrows_on_wrap = true -ij_markdown_keep_indents_on_empty_lines = false -ij_markdown_keep_line_breaks_inside_text_blocks = true -ij_markdown_max_lines_around_block_elements = 1 -ij_markdown_max_lines_around_header = 1 -ij_markdown_max_lines_between_paragraphs = 1 -ij_markdown_min_lines_around_block_elements = 1 -ij_markdown_min_lines_around_header = 1 -ij_markdown_min_lines_between_paragraphs = 1 -ij_markdown_wrap_text_if_long = true -ij_markdown_wrap_text_inside_blockquotes = true - -[{*.yaml,*.yml}] -indent_size = 2 -ij_yaml_align_values_properties = do_not_align -ij_yaml_autoinsert_sequence_marker = true -ij_yaml_block_mapping_on_new_line = false -ij_yaml_indent_sequence_value = true -ij_yaml_keep_indents_on_empty_lines = false -ij_yaml_keep_line_breaks = true -ij_yaml_sequence_on_new_line = false -ij_yaml_space_before_colon = false -ij_yaml_spaces_within_braces = true -ij_yaml_spaces_within_brackets = true diff --git a/.env.ci b/.env.ci index 64e572b64f2..f6c2a2c7004 100644 --- a/.env.ci +++ b/.env.ci @@ -8,14 +8,14 @@ LOG_CHANNEL=stack LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug -DB_CONNECTION=mysql +DB_CONNECTION=pgsql DB_HOST=database -DB_PORT=3306 +DB_PORT=5432 DB_DATABASE=convoy DB_USERNAME=convoy_user DB_PASSWORD=YzLa2BCBwDGWVkpG -CACHE_DRIVER=redis +CACHE_STORE=redis FILESYSTEM_DISK=local QUEUE_CONNECTION=redis SESSION_DRIVER=redis diff --git a/.env.docker.example b/.env.docker.example new file mode 100644 index 00000000000..5edb0a37f3b --- /dev/null +++ b/.env.docker.example @@ -0,0 +1,93 @@ +# Convoy production environment. +# +# This one file does two jobs: Docker Compose reads it to fill in ${...} in +# compose.yml, and every container receives it as its environment. Values here +# therefore override the defaults baked into the image. +# +# Two consequences worth knowing before you edit: +# * A literal `$` in a value is interpreted by Compose. Generated secrets stay +# hex/base64 for exactly this reason -- if you set a password by hand that +# contains `$`, write it as `$$`. +# * APP_KEY must be identical for the web, worker and scheduler containers. +# They all read this file, so just never change it after first boot: it +# decrypts existing sessions and encrypted columns. + +APP_NAME=Convoy +APP_ENV=production +APP_DEBUG=false + +# Generated by the installer: `php artisan key:generate --show`. +APP_KEY= + +# The hostname customers reach the panel on, with no scheme and no trailing +# slash. Compose builds Caddy's listen addresses from it, so changing it means +# re-issuing certificates. +APP_DOMAIN=panel.example.com + +# The full public URL, used for password-reset links, SSO deep links and asset +# paths. Should agree with APP_DOMAIN. +APP_URL=https://panel.example.com + +# `on` -- obtain a real certificate over ACME. Requires APP_DOMAIN to resolve +# to this host and ports 80/443 to be reachable from the internet. +# `off` -- serve the self-signed certificate the image generates on boot. Use +# this when reaching the panel by IP (Let's Encrypt will not issue for +# a bare IP) or when terminating TLS somewhere upstream. +CONVOY_AUTO_HTTPS=on + +# Image tag to run. Pin to a release (e.g. v10.1.0) if you would rather approve +# upgrades explicitly than take whatever `latest` is at the moment you pull. +CONVOY_VERSION=latest + +# Comma-separated IPs/CIDRs of proxies whose forwarded client-IP headers Convoy +# may trust. Leave unset when this host faces the internet directly. Set it to +# your load balancer's address when one sits in front, or client IPs in the +# audit log and rate limiter will all read as the balancer. Never `*` on a +# public origin. +TRUSTED_PROXIES= + +APP_TIMEZONE=UTC +APP_LOCALE=en + +# `cache` rather than `file` so that `artisan down` takes all three containers +# down together instead of only the one the command ran in. The store it uses +# defaults to redis in config/app.php. +APP_MAINTENANCE_DRIVER=cache + +# `postgres` is the bundled container. Point this at your own host if you would +# rather run your own database -- see docs/deployment.md. +DB_CONNECTION=pgsql +DB_HOST=postgres +DB_PORT=5432 +DB_DATABASE=convoy +DB_USERNAME=convoy +DB_PASSWORD= + +# `redis` is the bundled container. Redis is required, not optional: Horizon, +# the cache and the session store all live here. +REDIS_HOST=redis +REDIS_PORT=6379 +REDIS_PASSWORD= + +CACHE_STORE=redis +QUEUE_CONNECTION=redis +SESSION_DRIVER=redis +SESSION_LIFETIME=525600 +FILESYSTEM_DISK=local +SETTINGS_CACHE_ENABLED=true + +LOG_CHANNEL=stderr +LOG_LEVEL=info + +MAIL_MAILER=smtp +MAIL_HOST= +MAIL_PORT=587 +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION=tls +MAIL_FROM_ADDRESS=convoy@example.com +MAIL_FROM_NAME=Convoy + +# Optional integrations -- metric history, SSO deep links and OAuth/OIDC login. +# See .env.example for the full annotated list. +VICTORIAMETRICS_URL= diff --git a/.env.example b/.env.example index fb7edb7a5f6..5a847a5c7d4 100644 --- a/.env.example +++ b/.env.example @@ -1,29 +1,34 @@ +# Convoy's local development environment. +# +# These are the variables you actually need to get a working install. Everything +# else has a sensible default in config/ -- see .env.reference for the complete +# annotated list, or docs/configuration.md for what each one does. + APP_NAME=Convoy APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://localhost -LOG_CHANNEL=stack -LOG_DEPRECATIONS_CHANNEL=null -LOG_LEVEL=debug - -DB_CONNECTION=mysql +DB_CONNECTION=pgsql DB_HOST=database -DB_PORT=3306 +DB_PORT=5432 DB_DATABASE=convoy DB_USERNAME=convoy_user DB_PASSWORD= -CACHE_DRIVER=redis -FILESYSTEM_DISK=local +REDIS_HOST=redis +REDIS_PORT=6379 +REDIS_PASSWORD= + +# Redis is required, not optional: Horizon, the cache and sessions all use it. +CACHE_STORE=redis QUEUE_CONNECTION=redis SESSION_DRIVER=redis -SESSION_LIFETIME=525600 -REDIS_HOST=redis -REDIS_PASSWORD= -REDIS_PORT=6379 +# A year, in minutes. Laravel's default is two hours, which signs operators out +# of the panel far too aggressively for the way it is actually used. +SESSION_LIFETIME=525600 MAIL_MAILER=smtp MAIL_HOST=mailhog @@ -35,4 +40,4 @@ MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}" PHP_XDEBUG=false -PHP_XDEBUG_MODE='debug' \ No newline at end of file +PHP_XDEBUG_MODE='debug' diff --git a/.env.reference b/.env.reference new file mode 100644 index 00000000000..58020195c41 --- /dev/null +++ b/.env.reference @@ -0,0 +1,240 @@ +# Convoy configuration reference. +# +# Every variable Convoy reads, with its default. This file is documentation, not +# a template -- do not copy it over your .env. Start from .env.example (local +# development) or .env.docker.example (production), and add only the lines you +# actually want to change. +# +# Variables shown commented out are set to their default value. Uncommenting one +# without changing it does nothing. +# +# Prose explanations of each group live in docs/configuration.md. + +############################################################################## +# Application +############################################################################## + +APP_NAME=Convoy + +# local | production. Anything other than `local` disables developer conveniences. +APP_ENV=production + +# 32 random bytes, base64 encoded: `php artisan key:generate`. Every process +# (web, queue worker, scheduler) must share the same value -- it decrypts +# sessions and encrypted columns, so changing it invalidates both. +APP_KEY= + +# Never true on an internet-facing install: the debug page renders configuration +# and stack traces to whoever triggered the error. +APP_DEBUG=false + +# The URL customers reach the panel on, including scheme. Password-reset links, +# SSO deep links and asset URLs are all built from this. +APP_URL=https://panel.example.com + +#APP_TIMEZONE=UTC +#APP_LOCALE=en + +# file | cache. `file` marks down only the process that ran `artisan down`, which +# is correct for a single-process install. Deployments that run the web, worker +# and scheduler as separate processes want `cache`, so all three go down at once. +#APP_MAINTENANCE_DRIVER=file + +# Which cache store maintenance mode lives in when the driver is `cache`. +# Convoy defaults this to redis; Laravel's own default (`database`) expects a +# table Convoy does not have. +#APP_MAINTENANCE_STORE=redis + +# Comma-separated IPs/CIDRs for reverse proxies whose forwarded client-IP headers +# Convoy may trust. Leave unset when clients reach this host directly. Set it to +# your load balancer when one sits in front, or the audit log and rate limiter +# will record the balancer's address as the client. Never `*` on a public origin. +TRUSTED_PROXIES= + +############################################################################## +# Database +############################################################################## + +DB_CONNECTION=pgsql +DB_HOST=database +DB_PORT=5432 +DB_DATABASE=convoy +DB_USERNAME=convoy_user +DB_PASSWORD= + +############################################################################## +# Redis +############################################################################## +# Required. Horizon, the cache and the session store all depend on it. + +REDIS_HOST=redis +REDIS_PORT=6379 +REDIS_PASSWORD= + +CACHE_STORE=redis +QUEUE_CONNECTION=redis +SESSION_DRIVER=redis + +# A year, in minutes. Laravel's default of 120 signs operators out too eagerly. +SESSION_LIFETIME=525600 + +#FILESYSTEM_DISK=local + +############################################################################## +# Logging +############################################################################## + +# `stderr` for containers, so output lands in `docker logs`. `stack` writes files +# under storage/logs, which is what you want for a bare-metal install. +#LOG_CHANNEL=stack +#LOG_LEVEL=debug +#LOG_DEPRECATIONS_CHANNEL=null + +############################################################################## +# Mail +############################################################################## + +MAIL_MAILER=smtp +MAIL_HOST= +MAIL_PORT=587 +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION=tls +MAIL_FROM_ADDRESS="convoy@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +# Only when MAIL_MAILER=mailgun. +#MAILGUN_DOMAIN= +#MAILGUN_SECRET= +#MAILGUN_ENDPOINT=api.mailgun.net + +############################################################################## +# Queue dashboard (Horizon) +############################################################################## + +# Serve Horizon from a dedicated subdomain, or from a path other than /horizon. +#HORIZON_DOMAIN= +#HORIZON_PATH=horizon + +############################################################################## +# Settings cache +############################################################################## + +# spatie/laravel-settings: cache resolved settings so reads do not hit the +# database. Invalidated automatically on save. Leave enabled in production. +#SETTINGS_CACHE_ENABLED=true + +# Additionally memoize within a single request. Off by default because it makes +# settings written mid-request invisible to the rest of that request. +#SETTINGS_CACHE_MEMO=false + +############################################################################## +# Retention and pruning +############################################################################## +# All consumed by the scheduled prune commands in routes/console.php. + +# Days of audit log to keep. Security events are exempt and never pruned. +#APP_AUDIT_PRUNE_DAYS=90 + +# Days a backup is kept before it is eligible for pruning. +#BACKUP_PRUNE_AGE=360 + +# Days of deployment records to keep. +#DEPLOYMENT_RETENTION_PERIOD=90 + +# Minutes after which a deployment still in progress is treated as stuck. +#DEPLOYMENT_STUCK_AGE=1440 + +############################################################################## +# Rate limits +############################################################################## + +# At most BACKUP_THROTTLE_LIMIT backups per server per BACKUP_THROTTLE_PERIOD +# seconds. +#BACKUP_THROTTLE_LIMIT=2 +#BACKUP_THROTTLE_PERIOD=600 + +############################################################################## +# Outbound HTTP +############################################################################## +# Applied to calls out to Proxmox and Anchor. Raise the timeout if a hypervisor +# is slow to answer; raising it too far makes a wedged node stall queue workers. + +#GUZZLE_CONNECT_TIMEOUT=5 +#GUZZLE_TIMEOUT=15 + +############################################################################## +# Update checks +############################################################################## + +# The repository the admin dashboard checks for newer releases. +#UPDATE_CHECK_REPOSITORY=ConvoyPanel/panel + +############################################################################## +# Metrics (optional) +############################################################################## + +# VictoriaMetrics endpoint backing the admin dashboard's metric history (deltas +# and sparklines). Leave unset to disable -- the dashboard works without it. +VICTORIAMETRICS_URL= + +############################################################################## +# SSO deep links (optional) +############################################################################## +# Mint via POST /api/application/users/{user}/generate-sso-token. + +# Signed-link lifetime, in seconds. +#SSO_LINK_TTL=60 + +# Log channel each consumed link is written to. Defaults to LOG_CHANNEL. +#SSO_AUDIT_CHANNEL= + +############################################################################## +# OAuth / OIDC federated login (optional) +############################################################################## +# Convoy acts as the Relying Party -- see config/oauth.php. A provider appears on +# the login screen only when its *_ENABLED flag is true AND its client id and +# secret are both set. + +# Auto-create a (non-admin) user for an identity that matches no existing account. +#OAUTH_REGISTRATION=false + +# Link a provider identity to an existing account by verified email address. +#OAUTH_LINK_BY_VERIFIED_EMAIL=true + +#OAUTH_GOOGLE_ENABLED=true +#OAUTH_GOOGLE_CLIENT_ID= +#OAUTH_GOOGLE_CLIENT_SECRET= +#OAUTH_GOOGLE_REDIRECT_URI=/api/auth/oauth/google/callback + +#OAUTH_GITHUB_ENABLED=true +#OAUTH_GITHUB_CLIENT_ID= +#OAUTH_GITHUB_CLIENT_SECRET= +#OAUTH_GITHUB_REDIRECT_URI=/api/auth/oauth/github/callback + +#OAUTH_GITLAB_ENABLED=true +#OAUTH_GITLAB_CLIENT_ID= +#OAUTH_GITLAB_CLIENT_SECRET= +#OAUTH_GITLAB_REDIRECT_URI=/api/auth/oauth/gitlab/callback + +# Generic OpenID Connect against any standards-compliant IdP (Keycloak, +# Authentik, Okta, ...). OAUTH_OIDC_BASE_URL is the issuer; the endpoints are +# read from its /.well-known/openid-configuration. The explicit *_URL overrides +# below are only needed when discovery is non-standard. +#OAUTH_OIDC_ENABLED=true +#OAUTH_OIDC_LABEL="Company SSO" +#OAUTH_OIDC_BASE_URL=https://idp.example.com/realms/main +#OAUTH_OIDC_CLIENT_ID= +#OAUTH_OIDC_CLIENT_SECRET= +#OAUTH_OIDC_SCOPES=profile,email +#OAUTH_OIDC_REDIRECT_URI=/api/auth/oauth/oidc/callback +#OAUTH_OIDC_AUTH_URL= +#OAUTH_OIDC_TOKEN_URL= +#OAUTH_OIDC_USERINFO_URL= + +############################################################################## +# Local development only +############################################################################## + +#PHP_XDEBUG=false +#PHP_XDEBUG_MODE='debug' diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index c93982bde97..f4036ec33f1 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,91 +1,128 @@ name: Bug Report description: Something isn't working quite right in the software. -labels: [ bug,not confirmed ] +type: Bug +labels: [not confirmed] body: - type: markdown attributes: value: | - Bug reports should only be used for reporting issues with how the software works. For assistance installing this software, as well as debugging issues with dependencies, please use our [Discord server](https://discord.convoypanel.com). + Bug reports are for issues with how the software works. For help installing Convoy, or for + debugging your own host, Proxmox cluster or networking, please use our + [Discord server](https://discord.convoypanel.com) instead. + + - type: checkboxes + id: preflight + attributes: + label: Before you open this issue + options: + - label: I have [searched the existing issues](https://github.com/ConvoyPanel/panel/issues?q=is%3Aissue) and this has not been reported. + required: true + - label: I have checked in the Discord server and believe this is a bug in the software, not a configuration issue with my system. + required: true + - label: I am running a supported version of Convoy and have upgraded to the latest release where practical. + required: true - type: textarea + id: current-behavior attributes: label: Current Behavior - description: Please provide a clear & concise description of the issue. + description: A clear and concise description of what actually happens. validations: required: true - type: textarea + id: expected-behavior attributes: label: Expected Behavior - description: Please describe what you expected to happen. + description: What you expected to happen instead. validations: required: true - type: textarea + id: steps-to-reproduce attributes: label: Steps to Reproduce - description: Please be as detailed as possible when providing steps to reproduce, failure to provide steps will result in this issue being closed. + description: | + Numbered steps someone else can follow on a fresh install. Issues without steps to reproduce + will be closed. + placeholder: | + 1. Go to '...' + 2. Click on '...' + 3. See error validations: required: true - - type: textarea + - type: input + id: panel-version attributes: - label: Screenshots - description: If applicable, add screenshots to help explain your problem. + label: Panel Version + description: The version shown in the panel's footer. "latest" is not a version. + placeholder: 4.6.1 + validations: + required: true - - type: input + - type: dropdown + id: install-method attributes: - label: Proxmox OS Version - description: The version of your Proxmox node - placeholder: 7.4-13 + label: How did you install Convoy? + options: + - The one-command installer (install.convoypanel.com) + - Docker Compose, managed myself + - Upgraded from a pre-4.x install + - Other (explain in Additional Context) validations: required: true - type: input + id: host-os attributes: - label: Operating System - description: The OS you are using on your own computer to use Convoy. - placeholder: Windows 11 22H2 + label: Panel Host OS + description: The operating system of the host running the panel. + placeholder: Debian 13 validations: required: true - type: input + id: proxmox-version attributes: - label: Browser - description: Your browser and its version - placeholder: e.g. Chrome 69, Firefox 420, Chromium 69, Edge 420 + label: Proxmox VE Version + description: The version of the Proxmox node the affected server lives on. + placeholder: 8.4.1 validations: required: true - - type: textarea + - type: input + id: anchor-version attributes: - label: Additional Context - description: Add any other context about the problem here. + label: Anchor Version + description: The version of the Anchor agent on the affected node, if you know it. + placeholder: 0.1.0-alpha.1 - type: input - id: panel-version + id: browser attributes: - label: Panel Version - description: Version number of your Panel (latest is not a version) - placeholder: 3.10.0-beta - validations: - required: true + label: Browser + description: Only needed if the bug is visible in the interface. + placeholder: Chrome 141, Firefox 143, Safari 26 - - type: input - id: panel-logs + - type: textarea + id: logs attributes: label: Error Logs description: | - Check out [this page on our documentation](https://convoypanel.com/docs/project/support.html#collecting-panel-logs) for the log collector utility. You will need to run this on the server - hosting your instance of Convoy. - placeholder: "https://paste.frocdn.com/" + Run `convoyctl logs web` on the panel host (add `convoyctl logs worker` if the bug involves a + server action that never finished). Paste the relevant output below, or link a + [gist](https://gist.github.com) if it is long. Redact tokens, passwords and customer data. + render: shell - - type: checkboxes + - type: textarea + id: screenshots attributes: - label: Is there an existing issue for this? - description: Please [search here](https://github.com/convoypanel/panel/issues) to see if an issue already exists for your problem. - options: - - label: I have searched the existing issues before opening this issue. - required: true - - label: I have checked in the Discord server and believe this is a bug with the software, and not a configuration issue with my specific system. - required: true + label: Screenshots + description: If applicable, add screenshots to help explain the problem. + + - type: textarea + id: additional-context + attributes: + label: Additional Context + description: Anything else that might matter — reverse proxies, non-default settings, recent changes. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index d766d8a6968..fb755732335 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -8,4 +8,4 @@ contact_links: about: Please visit our Discord for general questions about Convoy. - name: Documentation url: https://convoypanel.com - about: Our documentation may have an answer for your issue/question. \ No newline at end of file + about: Our documentation may have an answer for your issue/question. diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index 3e570f22bc0..5d4758aed99 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -1,30 +1,54 @@ name: Feature Request description: Suggest a new feature or improvement for the software. -labels: [enhancement] +type: Feature body: - type: checkboxes + id: preflight attributes: - label: Is there an existing feature request for this? - description: Please [search here](https://github.com/convoypanel/panel/issues?q=is%3Aissue) to see if someone else has already suggested this. + label: Before you open this issue options: - - label: I have searched the existing issues before opening this feature request. + - label: I have [searched the existing issues](https://github.com/ConvoyPanel/panel/issues?q=is%3Aissue) and this has not already been suggested. required: true - type: textarea + id: problem attributes: - label: Describe the feature you would like to see. - description: "A clear & concise description of the feature you'd like to have added, and what issues it would solve." + label: What problem does this solve? + description: | + Describe the situation you run into today and why the current behaviour falls short. Concrete + examples from running Convoy in production are far more persuasive than a feature name. validations: required: true - type: textarea + id: solution attributes: label: Describe the solution you'd like. - description: "You must explain how you'd like to see this feature implemented. Technical implementation details are not necessary, rather an idea of how you'd like to see this feature used." + description: | + How would you like to see this work? Technical implementation details are not necessary — + describe how you would use the feature. validations: required: true - type: textarea + id: alternatives + attributes: + label: What are you doing instead today? + description: Workarounds, scripts, or other tooling you use to cover this gap. + + - type: dropdown + id: audience + attributes: + label: Who does this affect? + multiple: true + options: + - Administrators running the panel + - End users / customers with servers + - Resellers or downstream clients + - API consumers and integrations + + - type: textarea + id: additional-context attributes: label: Additional context to this request. - description: "Add any other context or screenshots about the feature request." \ No newline at end of file + description: Any other context, mockups or screenshots. diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 00000000000..cd8fb0263ca --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,357 @@ +name: CLA + +on: + pull_request_target: + types: [opened, synchronize, reopened, ready_for_review, edited] + issue_comment: + types: [created] + +permissions: + contents: read + issues: write + pull-requests: read + statuses: write + +env: + CLA_DOCUMENT_PATH: CONTRIBUTOR_LICENSE_AGREEMENT + # Required: set repository variable CLA_SIGNATURE_REPOSITORY to owner/private-repo + # and repository secret CLA_SIGNATURE_TOKEN to a token with contents:write access. + CLA_SIGNATURE_REPOSITORY: ${{ vars.CLA_SIGNATURE_REPOSITORY }} + CLA_SIGNATURE_TOKEN: ${{ secrets.CLA_SIGNATURE_TOKEN }} + CLA_SIGNATURE_BRANCH: main + CLA_SIGNATURE_PATH: .github/cla-signatures.json + CLA_STATUS_CONTEXT: CLA + CLA_SIGNING_STATEMENT: I am at least 18 years old, I have read the Performave Individual Contributor License Agreement, and I electronically sign and agree to it. + CLA_ALLOWLIST: dependabot[bot],renovate[bot],github-actions[bot] + +jobs: + cla: + name: Verify contributor license agreement + if: github.event_name == 'pull_request_target' || (github.event_name == 'issue_comment' && github.event.issue.pull_request) + runs-on: ubuntu-latest + + steps: + - name: Check CLA signatures + uses: actions/github-script@v7 + with: + script: | + const marker = ''; + const owner = context.repo.owner; + const repo = context.repo.repo; + const documentPath = process.env.CLA_DOCUMENT_PATH; + const configuredSignatureRepository = (process.env.CLA_SIGNATURE_REPOSITORY || '').trim(); + const signatureToken = (process.env.CLA_SIGNATURE_TOKEN || '').trim(); + const signatureBranch = process.env.CLA_SIGNATURE_BRANCH; + const signaturePath = process.env.CLA_SIGNATURE_PATH; + const statusContext = process.env.CLA_STATUS_CONTEXT; + const signingStatement = process.env.CLA_SIGNING_STATEMENT; + const allowlist = new Set( + process.env.CLA_ALLOWLIST.split(',') + .map((value) => value.trim().toLowerCase()) + .filter(Boolean), + ); + + const [signatureOwner, signatureRepo, extraSignatureRepoPart] = configuredSignatureRepository.split('/'); + + if (!signatureOwner || !signatureRepo || extraSignatureRepoPart) { + throw new Error('CLA_SIGNATURE_REPOSITORY must be set and formatted as owner/repo'); + } + + if (!signatureToken) { + throw new Error('CLA_SIGNATURE_TOKEN is required'); + } + + const signatureRequest = (route, parameters) => { + const headers = signatureToken + ? { ...(parameters.headers || {}), authorization: `Bearer ${signatureToken}` } + : parameters.headers; + + return github.request(route, { ...parameters, headers }); + }; + + const isIssueComment = context.eventName === 'issue_comment'; + const commentBody = isIssueComment ? context.payload.comment.body.trim() : ''; + const isSigningComment = commentBody === signingStatement; + const isRecheckComment = ['recheck cla', '/recheck-cla'].includes(commentBody.toLowerCase()); + + if (isIssueComment && !isSigningComment && !isRecheckComment) { + return; + } + + const prNumber = isIssueComment ? context.payload.issue.number : context.payload.pull_request.number; + const { data: pullRequest } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber }); + const headSha = pullRequest.head.sha; + const baseRef = pullRequest.base.ref; + const baseSha = pullRequest.base.sha; + + const isBot = (user) => { + if (!user) return false; + return user.type === 'Bot' || user.login.endsWith('[bot]') || allowlist.has(user.login.toLowerCase()); + }; + + const userKey = (user) => String(user.id); + + const ensureSignatureBranch = async () => { + try { + await signatureRequest('GET /repos/{owner}/{repo}/git/ref/{ref}', { + owner: signatureOwner, + repo: signatureRepo, + ref: `heads/${signatureBranch}`, + }); + } catch (error) { + if (error.status !== 404) throw error; + + const { data: signatureRepository } = await signatureRequest('GET /repos/{owner}/{repo}', { + owner: signatureOwner, + repo: signatureRepo, + }); + + const { data: defaultRef } = await signatureRequest('GET /repos/{owner}/{repo}/git/ref/{ref}', { + owner: signatureOwner, + repo: signatureRepo, + ref: `heads/${signatureRepository.default_branch}`, + }); + + await signatureRequest('POST /repos/{owner}/{repo}/git/refs', { + owner: signatureOwner, + repo: signatureRepo, + ref: `refs/heads/${signatureBranch}`, + sha: defaultRef.object.sha, + }); + } + }; + + const getAgreement = async () => { + const { data } = await github.rest.repos.getContent({ owner, repo, path: documentPath, ref: baseRef }); + if (Array.isArray(data) || data.type !== 'file') { + throw new Error(`${documentPath} must be a file`); + } + + return { + blobSha: data.sha, + url: `${context.serverUrl}/${owner}/${repo}/blob/${baseSha}/${documentPath}`, + }; + }; + + const getSignatureFile = async () => { + await ensureSignatureBranch(); + + try { + const { data } = await signatureRequest('GET /repos/{owner}/{repo}/contents/{path}', { + owner: signatureOwner, + repo: signatureRepo, + path: signaturePath, + ref: signatureBranch, + }); + + if (Array.isArray(data) || data.type !== 'file') { + throw new Error(`${signaturePath} must be a file`); + } + + const records = JSON.parse(Buffer.from(data.content, 'base64').toString('utf8')); + if (!Array.isArray(records.signatures)) { + throw new Error(`${signaturePath} must contain a signatures array`); + } + + return { + sha: data.sha, + records, + }; + } catch (error) { + if (error.status !== 404) throw error; + + return { + sha: undefined, + records: { + version: 1, + agreementPath: documentPath, + signatures: [], + }, + }; + } + }; + + const saveSignatureFile = async (file, message) => { + await signatureRequest('PUT /repos/{owner}/{repo}/contents/{path}', { + owner: signatureOwner, + repo: signatureRepo, + path: signaturePath, + branch: signatureBranch, + sha: file.sha, + message, + content: Buffer.from(`${JSON.stringify(file.records, null, 2)}\n`, 'utf8').toString('base64'), + }); + }; + + const listPullRequestContributors = async () => { + const contributors = new Map(); + const unknownCommits = []; + + if (!isBot(pullRequest.user)) { + contributors.set(userKey(pullRequest.user), pullRequest.user); + } + + const commits = await github.paginate(github.rest.pulls.listCommits, { + owner, + repo, + pull_number: prNumber, + per_page: 100, + }); + + for (const commit of commits) { + if (commit.author && !isBot(commit.author)) { + contributors.set(userKey(commit.author), commit.author); + continue; + } + + if (!commit.author) { + unknownCommits.push({ + sha: commit.sha.slice(0, 12), + name: commit.commit.author.name, + email: commit.commit.author.email, + }); + } + } + + return { contributors: [...contributors.values()], unknownCommits }; + }; + + const createCommitStatus = async (state, description) => { + await github.rest.repos.createCommitStatus({ + owner, + repo, + sha: headSha, + state, + context: statusContext, + description: description.slice(0, 140), + target_url: pullRequest.html_url, + }); + }; + + const upsertStatusComment = async (body) => { + const comments = await github.paginate(github.rest.issues.listComments, { + owner, + repo, + issue_number: prNumber, + per_page: 100, + }); + + const existing = comments.find((comment) => comment.body.includes(marker)); + + if (existing) { + await github.rest.issues.updateComment({ + owner, + repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner, + repo, + issue_number: prNumber, + body, + }); + } + }; + + const agreement = await getAgreement(); + const signatureFile = await getSignatureFile(); + + if (isSigningComment) { + const signer = context.payload.comment.user; + + if (isBot(signer)) { + await github.rest.reactions.createForIssueComment({ + owner, + repo, + comment_id: context.payload.comment.id, + content: '-1', + }); + throw new Error('Bot users cannot sign the CLA. Add trusted bots to CLA_ALLOWLIST instead.'); + } + + const alreadySigned = signatureFile.records.signatures.some((signature) => { + return signature.githubUserId === signer.id && signature.agreementBlobSha === agreement.blobSha; + }); + + if (!alreadySigned) { + signatureFile.records.signatures.push({ + githubLogin: signer.login, + githubUserId: signer.id, + signedAt: context.payload.comment.created_at, + repository: `${owner}/${repo}`, + pullRequest: prNumber, + commentId: context.payload.comment.id, + commentUrl: context.payload.comment.html_url, + agreementPath: documentPath, + agreementBlobSha: agreement.blobSha, + agreementUrl: agreement.url, + signingStatement, + }); + + await saveSignatureFile( + signatureFile, + `Record CLA signature for ${signer.login} on ${owner}/${repo}#${prNumber}`, + ); + } + + await github.rest.reactions.createForIssueComment({ + owner, + repo, + comment_id: context.payload.comment.id, + content: '+1', + }); + } + + const { contributors, unknownCommits } = await listPullRequestContributors(); + const signedUsers = new Set( + signatureFile.records.signatures + .filter((signature) => signature.agreementBlobSha === agreement.blobSha) + .map((signature) => String(signature.githubUserId)), + ); + const missing = contributors.filter((contributor) => !signedUsers.has(userKey(contributor))); + const hasUnknownCommits = unknownCommits.length > 0; + const hasPassed = missing.length === 0 && !hasUnknownCommits; + + const missingList = missing.length > 0 + ? missing.map((contributor) => `- @${contributor.login}`).join('\n') + : '- None'; + + const unknownList = hasUnknownCommits + ? unknownCommits.map((commit) => `- ${commit.sha} by ${commit.name} <${commit.email}>`).join('\n') + : '- None'; + + const body = `${marker} + ## Contributor License Agreement + + ${hasPassed ? 'All identified human contributors have signed the current CLA.' : 'This pull request cannot be merged until the CLA check passes.'} + + Current CLA: ${agreement.url} + + To sign, comment exactly: + + \`\`\`text + ${signingStatement} + \`\`\` + + This signature is only for individual contributors who are at least 18 years old. Do not use this workflow for contributions owned by a company, employer, client, school, or other legal entity; those require separate written permission or a separate contributor agreement. + + Missing signatures: + ${missingList} + + Commits without a linked GitHub author, requiring maintainer review: + ${unknownList} + + If you already signed, comment \`recheck cla\`. + `.replace(/^ {12}/gm, '').trim(); + + await upsertStatusComment(body); + + if (hasPassed) { + await createCommitStatus('success', 'All identified contributors signed the CLA'); + return; + } + + await createCommitStatus('failure', 'Missing CLA signatures or unlinked commit authors'); + core.setFailed('Missing CLA signatures or unlinked commit authors.'); diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000000..9c7491f8acb --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,159 @@ +name: Docker + +on: + push: + branches: + - main + tags: + - 'v*.*.*' + pull_request: + paths: + - 'Dockerfile' + - '.dockerignore' + - 'compose*.yml' + - 'docker/**' + - '.github/workflows/docker.yml' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository_owner }}/panel + +jobs: + # Each architecture is built on a runner of that architecture and pushed by + # digest; the manifest list is assembled afterwards. Building arm64 under QEMU + # on an amd64 runner works, but every PHP extension in the runtime stage is + # compiled from source, and emulating that turns a three-minute job into a + # thirty-minute one. + build: + name: build (${{ matrix.platform }}) + runs-on: ${{ matrix.runner }} + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-24.04 + - platform: linux/arm64 + runner: ubuntu-24.04-arm + outputs: + version: ${{ steps.meta.outputs.version }} + steps: + - uses: actions/checkout@v4 + + - name: Prepare platform pair + env: + PLATFORM: ${{ matrix.platform }} + run: echo "PLATFORM_PAIR=${PLATFORM//\//-}" >> "$GITHUB_ENV" + shell: bash + + - uses: docker/setup-buildx-action@v3 + + - uses: docker/metadata-action@v5 + id: meta + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - uses: docker/login-action@v3 + if: github.event_name != 'pull_request' + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v6 + with: + context: . + platforms: ${{ matrix.platform }} + build-args: | + CONVOY_VERSION=${{ steps.meta.outputs.version }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha,scope=${{ matrix.platform }} + cache-to: type=gha,mode=max,scope=${{ matrix.platform }} + # Attestations make the image verifiable in the supply-chain sense, + # which matters more than usual for something operators run as root + # on a hypervisor control node. + provenance: mode=max + sbom: true + outputs: type=image,name=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }} + + - name: Export digest + if: github.event_name != 'pull_request' + env: + DIGEST: ${{ steps.build.outputs.digest }} + run: | + mkdir -p /tmp/digests + touch "/tmp/digests/${DIGEST#sha256:}" + shell: bash + + - uses: actions/upload-artifact@v4 + if: github.event_name != 'pull_request' + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + name: publish manifest + runs-on: ubuntu-24.04 + needs: [build] + if: github.event_name != 'pull_request' + permissions: + contents: read + packages: write + steps: + - uses: actions/download-artifact@v4 + with: + path: /tmp/digests + pattern: digests-* + merge-multiple: true + + - uses: docker/setup-buildx-action@v3 + + - uses: docker/metadata-action@v5 + id: meta + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + # The default, `latest=auto`, hands `latest` to any non-prerelease + # semver tag on its own, which would quietly outvote the rule spelled + # out below rather than defer to it. Every tag is assigned here. + flavor: latest=false + # `latest` and a moving major tag let an operator choose between + # "always current" and "current within a major I have already + # validated"; the full semver tag is there to pin against. + # + # Branch builds are named after the branch, so the trunk publishes + # `main`. That name is doing more work than it looks: an operator puts + # it in CONVOY_VERSION, which compose.yml reads as an image tag *and* + # docker/install.sh feeds to raw.githubusercontent as a git ref to + # fetch the matching compose.yml. A tag that is not also a ref has to + # be special-cased there the way `latest` already is; a branch name + # never needs that. It also matches the version stamped into the + # image, which the build job derives from the same ref. + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} + type=ref,event=branch + + - uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Create manifest list + working-directory: /tmp/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@sha256:%s ' *) + shell: bash + + - name: Inspect + run: docker buildx imagetools inspect ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 18f06542c8f..3a5cc2b4a43 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,66 +10,78 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 + cache: 'npm' + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: gmp, pcntl, redis, pdo_pgsql, pgsql, bcmath, intl + coverage: none + tools: composer:v2 - name: Update Embedded Version String env: - REF: ${{ github.ref }} + VERSION: ${{ github.ref_name }} run: | - sed -i "s/ 'version' => 'canary',/ 'version' => '${REF:11}',/" config/app.php + # Match whatever version is committed, not the literal 'canary': when + # that value changes the substitution would otherwise silently do + # nothing and ship a release stamped with the wrong version. + sed -i "s/ 'version' => '[^']*',/ 'version' => '${VERSION#v}',/" config/app.php + grep -q " 'version' => '${VERSION#v}'," config/app.php - name: Build Assets run: | - npm install + cp .env.example .env + composer install --no-dev --prefer-dist --no-interaction --no-progress --optimize-autoloader + php artisan key:generate + npm ci npm run build + npm run tc + git diff --exit-code -- . ':(exclude)config/app.php' - name: Create Release Archive run: | - # Array of files and directories to remove files_to_remove=( "node_modules/" "tests/" "CODE_OF_CONDUCT.md" "CONTRIBUTOR_LICENSE_AGREEMENT" "crowdin.yml" - "docker-compose.ci.yml" "phpstan.neon" "phpunit.xml" "stats.html" ) - - # Loop over the files to remove and delete them rm -rf "${files_to_remove[@]}" - - # Array of specific dot files to include + files_to_include=( ".editorconfig" ".env.example" + ".env.reference" ".gitattributes" ".gitignore" ".prettierignore" ".prettierrc.json" ) - # Archive files, using * directly outside the array for proper expansion tar --exclude=panel.tar.gz -czf panel.tar.gz * "${files_to_include[@]}" - name: Extract Changelog id: extract_changelog env: - REF: ${{ github.ref }} + VERSION: ${{ github.ref_name }} run: | - sed -n "/^## ${REF:10}/,/^## /{/^## /b;p}" CHANGELOG.md > ./RELEASE_CHANGELOG - echo "version_name=${REF:10}" >> $GITHUB_OUTPUT + sed -n "/^## ${VERSION}/,/^## /{/^## /b;p}" CHANGELOG.md > ./RELEASE_CHANGELOG + echo "version_name=${VERSION}" >> "$GITHUB_OUTPUT" - name: Create Checksum and Add to Changelog run: | - SUM=`sha256sum panel.tar.gz` - echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG - echo $SUM > checksum.txt + SUM=$(sha256sum panel.tar.gz) + printf "\n#### SHA256 Checksum\n\n\`\`\`\n%s\n\`\`\`\n" "$SUM" >> ./RELEASE_CHANGELOG + echo "$SUM" > checksum.txt - name: Create Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: name: ${{ steps.extract_changelog.outputs.version_name }} body_path: ./RELEASE_CHANGELOG @@ -77,4 +89,4 @@ jobs: prerelease: ${{ contains(github.ref, 'beta') || contains(github.ref, 'alpha') || contains(github.ref, 'rc') }} files: | panel.tar.gz - checksum.txt \ No newline at end of file + checksum.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index f2976949f81..39f2ffff3b8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -2,36 +2,89 @@ name: Tests on: push: branches: + # A workflow only runs for pushes to a branch that contains it, so this + # list can only ever describe branches this file lives on. That is main: + # `next` is retired once it fast-forwards there, and 4.x carries its own + # copy of this workflow, so naming either here would look like coverage + # while doing nothing. - 'main' - - '3.0-develop' pull_request: jobs: tests: runs-on: ubuntu-latest + services: + postgres: + image: postgres:17 + env: + POSTGRES_DB: convoy + POSTGRES_USER: convoy_user + POSTGRES_PASSWORD: YzLa2BCBwDGWVkpG + ports: + - 5432:5432 + options: >- + --health-cmd="pg_isready -U convoy_user -d convoy" + --health-interval=5s + --health-timeout=5s + --health-retries=20 + + redis: + image: redis:7.0-alpine + ports: + - 6379:6379 + options: >- + --health-cmd="redis-cli ping" + --health-interval=5s + --health-timeout=5s + --health-retries=20 + steps: - uses: actions/checkout@v4 - - name: Create environment file - run: cp .env.ci .env + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: gmp, pcntl, redis, pdo_pgsql, pgsql, bcmath, intl + coverage: none + tools: composer:v2 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: 'npm' - - name: Start Docker Containers - run: docker compose -f docker-compose.ci.yml up -d + - name: Create environment file + run: | + cp .env.ci .env + sed -i 's/^DB_HOST=.*/DB_HOST=127.0.0.1/' .env + sed -i 's/^REDIS_HOST=.*/REDIS_HOST=127.0.0.1/' .env + sed -i 's/^REDIS_PASSWORD=.*/REDIS_PASSWORD=/' .env - name: Install Composer dependencies - run: docker compose -f docker-compose.ci.yml exec workspace composer install --prefer-dist --no-interaction --no-progress + run: composer install --prefer-dist --no-interaction --no-progress - name: Install NPM dependencies - run: docker compose -f docker-compose.ci.yml exec workspace npm install + run: npm ci - name: Build frontend assets - run: docker compose -f docker-compose.ci.yml exec workspace npm run build + run: npm run build + + - name: Type-check frontend + run: npm run tc + + - name: Assert generated sources are current + run: git diff --exit-code - name: Run database migrations - run: docker compose -f docker-compose.ci.yml exec workspace php artisan migrate + run: php artisan migrate --force - name: Run feature tests - run: docker compose -f docker-compose.ci.yml exec workspace vendor/bin/pest --bootstrap vendor/autoload.php tests/Feature + run: vendor/bin/pest tests/Feature - name: Run unit tests - run: docker compose -f docker-compose.ci.yml exec workspace vendor/bin/pest --bootstrap vendor/autoload.php tests/Unit \ No newline at end of file + run: vendor/bin/pest tests/Unit + + - name: Run static analysis + run: composer analyze -- --no-progress diff --git a/.gitignore b/.gitignore index a8dae5f3e43..470cb604092 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ /vendor .env .env.backup +/.sbx/tailnet .phpunit.result.cache Homestead.json Homestead.yaml @@ -13,10 +14,36 @@ npm-debug.log yarn-error.log /.idea /.vscode +# Claude Code: local/runtime state only. `.claude/settings.json` and any +# agents/, commands/, or skills/ are meant to be shared, so this stays an +# explicit list rather than ignoring /.claude wholesale. +/.claude/settings.local.json +/.claude/projects +/.claude/memory +/.claude/worktrees +/.claude/*.lock /supervisord.log /supervisord.pid _ide_*.php stats.html .fleet lang/php_*.json -.phpunit.cache \ No newline at end of file +# The email build's own dependency tree and its design-review page. The +# compiled views under resources/views/mail ARE committed, so a deploy never +# needs Node to render mail. +/emails/node_modules +/emails/preview +/resources/scripts/routeTree.gen.ts +/resources/scripts/wayfinder +/resources/scripts/types/generated.d.ts +/resources/scripts/types/typescript-transformer-manifest.json +.DS_Store +._.DS_Store +**/.DS_Store +**/._.DS_Store +.php-cs-fixer.cache +.phpunit.cache +# Scratch files from agent/browser-driven verification runs. +*.tmp.mjs +*.tmp.php +.tanstack/ diff --git a/.prettierignore b/.prettierignore index bac7f4dfcd0..af6d43246c3 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,7 @@ .github public node_modules -resources/views \ No newline at end of file +resources/views + +# Vendored verbatim from the shadcn package — must stay diffable upstream. +resources/scripts/lib/scroll-fade.css \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json index 1bf93220bb9..6549bb710c1 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,29 +1,26 @@ { "arrowParens": "avoid", - "bracketSameLine": false, - "bracketSpacing": true, - "embeddedLanguageFormatting": "auto", - "htmlWhitespaceSensitivity": "css", - "insertPragma": false, "jsxSingleQuote": true, - "printWidth": 80, - "proseWrap": "preserve", "quoteProps": "consistent", - "requirePragma": false, "semi": false, - "singleAttributePerLine": false, "singleQuote": true, "trailingComma": "es5", - "useTabs": false, - "vueIndentScriptAndStyle": false, "tabWidth": 4, "importOrderSeparation": true, "importOrderSortSpecifiers": true, "importOrder": [ + "", + "^@/lib/(.*)$", "^@/api/(.*)$", - "^@/components/elements/(.*)$", + "^@/components/layouts/(.*)$", + "^@/components/interfaces/(.*)$", + "^@/components/ui/(.*)$", "^@/components/(.*)$", + "^@/assets/(.*)$", "^[./]" ], - "plugins": ["@trivago/prettier-plugin-sort-imports"] + "plugins": [ + "@trivago/prettier-plugin-sort-imports", + "prettier-plugin-tailwindcss" + ] } diff --git a/.sbx/README.md b/.sbx/README.md new file mode 100644 index 00000000000..21bee38343f --- /dev/null +++ b/.sbx/README.md @@ -0,0 +1,44 @@ +# sbx kits + +Provisioning for running a coding agent in a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) +(`sbx`) against this repo. sbx has no auto-detection for repo-local kits, so a kit +is just a committed directory you reference explicitly with `--kit`. + +## `dev/` — Convoy dev environment + +Installs ddev and starts the stack inside the sandbox (its Docker daemon, DB, and +volumes are isolated from your host ddev). It also sets up headless browsing: +Playwright is pinned and installed to `/opt/sbx-e2e` (never the repo), and +`dev/browser.mjs` is published to `/opt/sbx-e2e/browser.mjs` for scripts to import. +Because `/etc/hosts` is a read-only mount in a sandbox — which otherwise makes +`ddev start` fail outright — a startup step overmounts a writable copy so ddev can +register `*.ddev.site`. See `docs/docker-sandbox.md`. + +```sh +sbx run --kit .sbx/dev claude +``` + +The first run installs ddev and pulls its images (slow, once). To make later +starts instant, snapshot the provisioned sandbox into a template: + +```sh +sbx template save convoy-dev +sbx run -t convoy-dev --kit .sbx/dev claude # install is now a no-op; only `ddev start` runs +``` + +Then finish app provisioning inside the sandbox (see the kit's `agentContext`, or +`.sbx/dev/spec.yaml`): + +```sh +ddev composer install +ddev exec php artisan migrate +ddev exec php artisan db:seed --class=DevNodeSeeder # needs PROXMOX_* in .env +``` + +## Boundaries + +- **Secrets** (e.g. `PROXMOX_*`) live in the gitignored `.env`, mounted into the + sandbox — never in a kit. +- **Notifications** and any personal network setup come from global kits in the + operator's own dotfiles, injected automatically by their `sbx` wrapper; `.sbx/dev` + is project provisioning only. Multiple `--kit` refs compose, so they layer cleanly. diff --git a/.sbx/dev/browser.mjs b/.sbx/dev/browser.mjs new file mode 100644 index 00000000000..cc019b3715f --- /dev/null +++ b/.sbx/dev/browser.mjs @@ -0,0 +1,104 @@ +/* + * Playwright helpers for driving the sandbox's own ddev app. + * + * The dev kit copies this to /opt/sbx-e2e/browser.mjs on every start, next to a + * pinned `playwright` install. Import it by absolute path from a throwaway + * script anywhere (e.g. your scratchpad) — resolving `playwright` relative to + * /opt/sbx-e2e means the repo never needs a devDependency for a local probe: + * + * import { BASE, launch, newContext, login, capture } from '/opt/sbx-e2e/browser.mjs' + * + * const browser = await launch() + * const ctx = await newContext(browser) + * const page = await login(ctx, { email: '…', password: '…' }) + * await capture(ctx, { url: '/admin/nodes', width: 768, path: '/tmp/nodes.png' }) + * await browser.close() + */ +import { chromium } from 'playwright' +import { execFileSync } from 'node:child_process' + +export const BASE = process.env.SBX_APP_URL ?? 'https://convoy.ddev.site' + +const PROXY = process.env.HTTPS_PROXY ?? 'http://gateway.docker.internal:3128' + +/* + * Chromium hands hostnames to the proxy rather than resolving them, and the + * sandbox proxy resolves them on the HOST — so an unbypassed request to + * convoy.ddev.site drives your real host app (leaked sessions, mutated data). + * Bypassing the proxy for the app keeps it on this sandbox's loopback; the + * preflight below is the backstop that refuses to run if it ever slips. + */ +const BYPASS = '.ddev.site,localhost,127.0.0.1' + +export function assertSandboxApp(base = BASE) { + const ip = execFileSync('curl', ['-sk', `${base}/up`, '-o', '/dev/null', '-w', '%{remote_ip}']) + .toString() + .trim() + + if (ip !== '127.0.0.1') { + throw new Error( + `refusing to drive ${base}: it answered from ${ip || '(unreachable)'}, not this ` + + `sandbox's ddev (127.0.0.1). Check 'ddev describe', that .ddev.site is in ` + + `NO_PROXY, and that /etc/hosts is the writable overmount the dev kit sets up.` + ) + } +} + +export async function launch(options = {}) { + assertSandboxApp() + + return chromium.launch({ proxy: { server: PROXY, bypass: BYPASS }, ...options }) +} + +// The ddev cert is mkcert-signed and that CA isn't in the sandbox trust store. +export async function newContext(browser, options = {}) { + return browser.newContext({ + ignoreHTTPSErrors: true, + viewport: { width: 1440, height: 1000 }, + deviceScaleFactor: 2, + ...options, + }) +} + +export async function login(context, { email, password } = {}) { + const page = await context.newPage() + + await page.goto(`${BASE}/auth/login`, { waitUntil: 'domcontentloaded' }) + await page.getByLabel(/email/i).fill(email ?? process.env.SBX_APP_EMAIL) + await page.getByLabel(/password/i).fill(password ?? process.env.SBX_APP_PASSWORD) + await page.getByRole('button', { name: /sign in|log in|login/i }).click() + await page.waitForURL(u => !u.pathname.includes('/auth/login'), { timeout: 30_000 }) + + return page +} + +/* + * Screenshot one route at one viewport. Returns the horizontal overflow in px, + * which is the layout failure mode worth failing a visual check on. + */ +export async function capture(context, { url, path, width = 1440, height = 1000, settle = 1000 }) { + const page = await context.newPage() + + try { + await page.setViewportSize({ width, height }) + await page.goto(BASE + url, { waitUntil: 'networkidle' }) + await page.waitForTimeout(settle) + await page.screenshot({ path, fullPage: true }) + + return page.evaluate( + () => document.documentElement.scrollWidth - document.documentElement.clientWidth + ) + } finally { + await page.close() + } +} + +// Attach before navigating; the returned array fills as the page misbehaves. +export function collectErrors(page) { + const errors = [] + + page.on('pageerror', e => errors.push(`pageerror: ${e.message}`)) + page.on('console', m => m.type() === 'error' && errors.push(`console: ${m.text()}`)) + + return errors +} diff --git a/.sbx/dev/spec.yaml b/.sbx/dev/spec.yaml new file mode 100644 index 00000000000..0e240dda062 --- /dev/null +++ b/.sbx/dev/spec.yaml @@ -0,0 +1,177 @@ +schemaVersion: "1" +kind: mixin +name: convoy-dev +displayName: Convoy dev sandbox +description: Provision ddev inside a Docker Sandbox for working on Convoy. + +# Appended to the agent's memory at sandbox creation — tells the agent how to +# finish provisioning and run common tasks. (ddev itself is installed/started by +# the commands below; these are the project-state steps that shouldn't run +# automatically.) +agentContext: | + # Convoy dev sandbox + + ddev is installed and started for you (Laravel + Postgres). Its **database** is + this sandbox's own, and the install step below proxy-isolates `*.ddev.site` + (adds it to NO_PROXY) so `curl`/Playwright hitting https://convoy.ddev.site stay + on THIS sandbox's ddev instead of being resolved by the proxy on the host and + driving your real host app. Sanity check after a rebuild: + `curl -sk https://convoy.ddev.site/ -o /dev/null -w '%{remote_ip}\n'` must print + `127.0.0.1` (not a proxy address). Background + the host-side + `sbx policy deny network '*.ddev.site'` backstop: docs/docker-sandbox.md. + + Playwright + Chromium are pre-installed for visual and e2e checks — but NOT in + the repo. They live in `/opt/sbx-e2e` (pinned version, browsers in + ~/.cache/ms-playwright), so **do not `npm install playwright` in the project**; + that would put sandbox-only tooling in package.json. Write throwaway scripts + wherever you like and import the helpers by absolute path: + + import { BASE, launch, newContext, login, capture } from '/opt/sbx-e2e/browser.mjs' + + const browser = await launch() // proxy-bypassed + preflighted + const ctx = await newContext(browser) // ignores the mkcert cert + const page = await login(ctx, { email: '…', password: '…' }) + await capture(ctx, { url: '/admin/nodes', width: 768, path: '/tmp/nodes.png' }) + await browser.close() + + `launch()` refuses to run unless the app answers from 127.0.0.1, so a + misconfigured sandbox fails loudly instead of driving your host app. Source: + `.sbx/dev/browser.mjs` (copied into place on every start — edit it there). + + If ddev is unreachable, fix ddev; never tunnel to the host's instance. + + Finish provisioning once: + + ddev composer install + ddev exec php artisan migrate + ddev exec php artisan db:seed --class=DevNodeSeeder # a Proxmox node from PROXMOX_* in .env + + Everyday: + + ddev exec php artisan test # test suite + ddev exec php artisan # artisan + ddev describe # status / URLs + + Note: vendor/ and node_modules/ are shared with your host repo via the mounted + workspace, so composer/npm installs here also land in your host checkout. + +commands: + # Runs ONCE at creation (as root unless a user is set). Slow the first time + # (installs ddev + Chromium). Bake it into a template so it isn't repeated: + # sbx template save convoy-dev + install: + # ddev's installer refuses to run as root and uses sudo itself, so run it as + # the agent user (uid 1000, which is in the sudo group). + - command: "command -v ddev >/dev/null 2>&1 || curl -fsSL https://ddev.com/install.sh | bash" + user: "1000" + description: install ddev + + # Keep *.ddev.site resolving to THIS sandbox's ddev (127.0.0.1) instead of the + # host's. The sandbox proxy otherwise resolves the hostname on the host side, so + # curl/Playwright silently drive your real host app (leaking e2e sessions, + # mutating host data). Marker-guarded because CLAUDE_ENV_FILE is sourced before + # every command — a plain append would grow NO_PROXY without bound. + - command: | + cat >> "${CLAUDE_ENV_FILE:-/etc/sandbox-persistent.sh}" <<'SBXEOF' + if [ -z "${SBX_DDEV_NOPROXY_DONE:-}" ]; then + export NO_PROXY="${NO_PROXY:+$NO_PROXY,}.ddev.site,ddev.site" + export no_proxy="$NO_PROXY" + export SBX_DDEV_NOPROXY_DONE=1 + fi + SBXEOF + description: proxy-isolate *.ddev.site from the host dev server + + # Playwright lives OUTSIDE the repo so a visual check never adds a devDependency + # to package.json. Scripts import /opt/sbx-e2e/browser.mjs by absolute path, and + # Node resolves `playwright` by walking up from there to /opt/sbx-e2e/node_modules. + - command: "install -d -o 1000 -g 1000 /opt/sbx-e2e" + description: create the sandbox-local e2e prefix + + # Pinned, not @latest: the browser build id is tied to the playwright version, so + # a floating version installed later in a session no longer matches the browsers + # baked in here and dies with "Executable doesn't exist at .../chromium-". + # A real package.json (rather than --no-save) is what keeps it installed — with + # nothing declared, the next npm command in this prefix prunes node_modules. + - command: | + set -eu + cat > /opt/sbx-e2e/package.json <<'PKGEOF' + { + "name": "sbx-e2e", + "private": true, + "type": "module", + "dependencies": { "playwright": "1.62.0" } + } + PKGEOF + npm --prefix /opt/sbx-e2e install --loglevel=error + user: "1000" + description: install Playwright (pinned) + + # Chromium's shared libraries via apt (needs root — the default here). + - command: "/opt/sbx-e2e/node_modules/.bin/playwright install-deps chromium || echo 'convoy-dev: playwright install-deps failed; agent can rerun on demand'" + description: install Chromium OS dependencies + + # The browser itself, as the agent user so it lands in the home cache the agent + # actually uses. Non-fatal so a download hiccup can't block creation. + - command: "/opt/sbx-e2e/node_modules/.bin/playwright install chromium || echo 'convoy-dev: playwright chromium preinstall skipped'" + user: "1000" + description: pre-install Chromium for visual/e2e checks + + # Runs on EVERY start (as the agent user). Fast once ddev's images are baked + # into a template. + startup: + # /etc/hosts is a read-only bind mount from the host, so ddev's hostname step + # ("Failed to add hosts entry … read-only file system") aborts `ddev start` — + # and *.ddev.site has no public DNS answer in here to fall back on. Overmount a + # writable copy so ddev can register its own names; the marker line makes it + # idempotent across restarts. Sandbox-local by construction: nothing is written + # to the workspace, and the overmount dies with the sandbox. + - command: + - "bash" + - "-lc" + - | + set -euo pipefail + mark='# sbx: writable hosts overmount' + if grep -qxF "$mark" /etc/hosts 2>/dev/null; then + echo 'convoy-dev: /etc/hosts already writable' + exit 0 + fi + tmp=$(mktemp) + { cat /etc/hosts; echo "$mark"; } > "$tmp" + sudo install -m 0644 -o root -g root "$tmp" /var/lib/sbx-hosts + rm -f "$tmp" + sudo mount --bind /var/lib/sbx-hosts /etc/hosts + echo 'convoy-dev: overmounted /etc/hosts (writable copy at /var/lib/sbx-hosts)' + description: make /etc/hosts writable so ddev can register *.ddev.site + + # Copied rather than symlinked: Node resolves a symlinked module to its realpath, + # which would send the `playwright` lookup into the repo instead of /opt/sbx-e2e. + - command: ["bash", "-lc", "install -m 0644 \"${WORKSPACE_DIR:-.}/.sbx/dev/browser.mjs\" /opt/sbx-e2e/browser.mjs"] + description: publish the Playwright helpers to /opt/sbx-e2e + + # ddev signs the project cert with the mkcert CA of whichever machine runs + # `ddev start`, and drops it in .ddev/traefik/certs — which is part of the + # mounted workspace. Left alone, this sandbox's throwaway CA overwrites the + # host's cert in the checkout, and the next host `ddev start` copies it into + # the host router: every *.ddev.site project on the Mac then fails TLS in + # the browser, until a host-side `ddev restart` regenerates it. Overmount a + # sandbox-local dir (the same trick as /etc/hosts above) so ddev in here + # signs its own certs and the host checkout is never written to. + - command: + - "bash" + - "-lc" + - | + set -euo pipefail + certs="${WORKSPACE_DIR:-.}/.ddev/traefik/certs" + mkdir -p "$certs" + certs=$(cd "$certs" && pwd -P) + if awk -v d="$certs" '$2 == d { found = 1 } END { exit !found }' /proc/self/mounts; then + echo 'convoy-dev: .ddev/traefik/certs already overmounted' + exit 0 + fi + sudo install -d -m 0755 -o 1000 -g 1000 /var/lib/sbx-ddev-certs + sudo mount --bind /var/lib/sbx-ddev-certs "$certs" + echo 'convoy-dev: overmounted .ddev/traefik/certs (sandbox-local)' + description: keep sandbox-signed ddev certs out of the host checkout + + - command: ["bash", "-lc", "cd \"${WORKSPACE_DIR:-.}\" && ddev start -y"] + description: boot the ddev stack diff --git a/ACKNOWLEDGEMENTS.md b/ACKNOWLEDGEMENTS.md deleted file mode 100644 index 31d90718f86..00000000000 --- a/ACKNOWLEDGEMENTS.md +++ /dev/null @@ -1,29 +0,0 @@ -# Acknowledgements - -## tslib - -``` -/****************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */ -``` - -## fakerphp/faker - -Translations are under the CC-BY-SA-3.0 license. -https://github.com/FakerPHP/Faker - -## caniuse-lite - -https://github.com/browserslist/caniuse-lite \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..c151d808366 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,213 @@ +# AGENTS.md + +## Generated frontend artifacts + +These are NOT committed (matches the existing `routeTree.gen.ts` convention): + +- `resources/scripts/routeTree.gen.ts` — TanStack Router file-based route tree +- `resources/scripts/wayfinder/` — Wayfinder typed route helpers +- `resources/scripts/types/generated.d.ts` — Spatie typescript-transformer output (DTOs + enums) +- `resources/scripts/types/typescript-transformer-manifest.json` + +Regenerate with `ddev npm run types:generate` (also runs automatically via `predev` / `prebuild`). CI should run the generators before typecheck/build; a clean-tree assertion afterwards catches anything that drifted. + +## Frontend code style + +**Arrow functions, not `function` declarations.** Components, hooks, helpers and +callbacks are all `const x = () => …`, with a separate `export default x` at the +bottom where a default export is needed. This is what the codebase already does +almost everywhere (`features/**`, `components/ui/**`); the few `function Foo()` +declarations left are strays, not a second accepted style. Convert them when you +touch them. + +## Frontend design consistency + +The UI must read as **one app**, not a patchwork of per-page styles. Before building any +screen, find the closest existing one and reuse its structure, spacing, and components — +do not invent new paddings, gaps, type scales, or bespoke card layouts. + +- **Reuse components, not one-offs.** Build on `components/ui/*` (`Card`, `Table`, + `Progress`, `Typography`, …). Match the established grid rhythm (`gap-2` / `gap-4`) and the + standard `Card` padding — don't hand-roll different padding per section. +- **Page actions never share the heading's row.** An `

` (`Heading`) owns its line — + only badges and a status indicator may sit beside it, and the identity line under it + (an email, an FQDN, a hostname) belongs to the heading, not to the actions. Every + control that *does* something — buttons, create dialogs, dropdowns, filter selects — + goes in a `PageToolbar` on the next row: filters as children on the left, actions on + the right, exactly where `DataTableToolbar` puts them. That way a page backed by a + table and a page backed by cards put their buttons at the same place and height, and a + long name never crushes the buttons against the right edge. Never re-create the row by + hand with `justify-between` or `ml-auto`. +- **Favor data density.** No large card wrapping a single small number. Pack related stats + into one card as a definition list (`
` with `
` + / `
`), the way `Client/Server/Overview/SpecificationsCard.tsx` does. A screen full of + near-empty cards is a smell. +- **Format consistently.** Bytes go through `byte-size` (`byteSize(n, { units: 'iec' })`), the + same as the rest of the app — not an ad-hoc formatter. + +When in doubt, mirror an existing page verbatim rather than introducing a new pattern. + +## Frontend copy + +The panel labels things; it does not narrate them. Most UI prose in this codebase was +written one screen at a time and drifted into a house voice — balanced clauses, a +semicolon, a knowing little reveal at the end — that reads like documentation being +recited at the user. Do not add more of it, and strip it when you touch a screen. + +- **Don't write page subtitles.** A page under an `

` gets no explanatory paragraph. + If the heading is a decent noun (`Audit Log`, `Users`, `Storage`), the gloss under it is + the heading again in more words. Delete it rather than rewriting it shorter. Same for + section headers inside a page. +- **Never state system policy in UI chrome.** Retention windows, precedence rules, sync + behavior, what the backend does on a schedule — these are not descriptions, they are + rules, and a subtitle is the wrong place to publish one. The tell is that the reader + can't act on it and it raises a question it doesn't answer: "operational events age + out" (after how long?), "once Convoy knows about it" (when is that?). If a rule genuinely + needs to be visible, attach it to the control or row it governs, with the real number + in it — otherwise leave it out. +- **Empty states say what's missing and the next action.** One short line, concrete and + imperative: `No storages` / `Add a storage on this node.` Not lore about how the system + will eventually notice ("Run the install command on a Proxmox host and it will show up + here, having already described itself."). +- **Cut the writerly cadence.** No semicolon-balanced pairs, no "not X, but Y", no + trailing participial reveal, no sentence whose job is tone. This applies to headers, + empty states, form hints, toasts, dialog bodies and tooltips alike — the disease is + everywhere, not just on page headers. +- **Prefer no text to filler text.** If you can't say something the user can act on, + the correct amount of copy is zero. + +## Frontend data layer + +Don't hand-roll what the wrappers already do. Per `features//api.ts`: + +- **Fetch** via `apiFetch` + a Wayfinder route object — never raw `axios`/`fetch` or hardcoded URLs. + Reads are `queryOptions` + a `useX` hook (`@tanstack/react-query`). +- **Mutate** with `useMutation`; update the cache with `useQueryMutator`, surface server errors with + `handleFormErrors(e, form.setError)`. Don't call `apiFetch` straight from a click handler. +- **Forms** are react-hook-form + `zodResolver`, with the `zod` schema exported from `api.ts`. Use the + `Form` field wrappers (`InputForm`, `SelectForm`, `CheckboxForm`, …) and `FormButton` — not bare + `Input`/`Select` + `useState`. +- **Clipboard** goes through the `useClipboard` hook, not `navigator.clipboard` directly. + +Reference: `features/locations`, `features/template-groups`. Admin controllers are served under both +`/api/admin` and `/api/application`, so Wayfinder emits URI-keyed dicts — reference the admin URI +explicitly (see `features/tokens/api.ts`). + +## Local development (ddev) + +Local dev runs on [ddev](https://ddev.com) with **Postgres 17**. One-time setup: + +```bash +ddev start # web + postgres + redis + horizon + scheduler +ddev composer install +ddev artisan migrate # or: ddev artisan migrate:fresh +ddev npm install && ddev npm run build +``` + +The app is served at https://convoy.ddev.site. For frontend HMR, run `ddev npm run dev` +(Vite is served at https://convoy.ddev.site:3000). + +Roll back the database while iterating on migrations (replaces the old Makefile snapshot hack): + +```bash +ddev snapshot --name pre-migration +ddev snapshot restore pre-migration +``` + +## Running PHP, Composer, Artisan, and npm + +There is no host-side `php` / `composer` / `node`; they run inside the ddev web container: + +- `ddev artisan ` — Artisan +- `ddev composer ` — Composer (the stack is up during `ddev start`, so + `post-autoload-dump`'s `package:discover` connects to cache/DB fine) +- `ddev npm ` — npm runs in-container (so `types:generate` can call + `php artisan` directly) +- `ddev ssh` — open a shell in the web container + +DB / Redis / mail are configured via `web_environment` in `.ddev/config.yaml`, whose values +override `.env` (Laravel's Dotenv does not overwrite real env vars). `ext-gmp` is added +via `webimage_extra_packages`. + +## Docker sandbox + +When developing inside an isolated **Docker Sandbox** (an AI agent's disposable VM), see +[docs/docker-sandbox.md](docs/docker-sandbox.md). In that environment you are free to install and +run whatever tooling you need to develop and test (it's throwaway and isolated — don't commit those +installs). It also documents the sandbox-local fix for `php artisan tinker` segfaulting +(PsySH `usePcntl` fork crash) and the intermittent heavy-command SIGSEGVs (retry). These are +sandbox-only notes — nothing there belongs in committed project config or CI. + +## Laravel style + +Prefer current, namespaced support APIs over legacy Laravel 5 helper aliases: use `Arr::get` +/ `Str::slug`, not `array_get` / `str_slug`. Current framework helpers such as `auth()`, +`config()`, `now()`, `filled()`, and `data_get()` are fine; use `$request->user()` when a +request is already available. + +## Proxmox VE API documentation + +Generated Proxmox VE API docs are in: + +- `docs/pve-api/llms.txt` - compact overview +- `docs/pve-api/search-index.json` - endpoint search index +- `docs/pve-api/endpoints.json` - normalized full endpoint data +- `docs/pve-api/markdown/endpoints/` - one Markdown page per endpoint +- `docs/pve-api/llms-full.txt` - full concatenated docs, use only when needed + +When answering Proxmox VE API questions: + +1. Read `docs/pve-api/llms.txt` first. +2. Use `search-index.json` or `endpoints.json` to find relevant endpoints. +3. Open the specific endpoint Markdown file for details. +4. Do not guess endpoint names from memory. + +## Proxmox data DTOs + +Model Proxmox data to *our* domain, not Proxmox's wire format. Don't mirror +their property-list layout or their terse/unclear key names (`ssd`, `secret`, +`ro`, `di`) 1:1 — rename to clear domain properties (`isEmulatingSSD`, +`tokenSecret`, `isReadonly`) and lean on PHP features JSON lacks, especially +**backed enums** for closed value sets instead of raw strings/ints. The mapping +back to Proxmox's keys/format is the codec's job (`App\Extensions\Spatie\Data\ +Proxmox` — `#[ProxmoxProperty]`, casts, `PropertyList`), so keep conversion +logic there and reusable, not re-implemented per DTO (e.g. byte-unit scaling). +5. Do not call the Proxmox API; these docs are reference-only. + +## Live End-to-End Testing + +The Proxmox credentials live in the project **`.env`** (`PROXMOX_FQDN`, `PROXMOX_TOKEN_ID`, +`PROXMOX_TOKEN_SECRET`, and usually `PROXMOX_NODE_NAME` / `PROXMOX_SSH_TARGET`). **They are read by +Laravel's Dotenv (`env()` / `config()`), NOT exported into the container shell** — so +`ddev exec sh -c 'echo $PROXMOX_FQDN'` prints nothing even when they are set. Do **not** conclude +from an empty `echo` that they are missing. To check, read the file directly (`grep -E '^PROXMOX_' +.env`) or ask Laravel (`ddev artisan tinker --execute="echo config('...')"`). In practice, assume +they are defined and just run the seeder — it warns and no-ops if they truly are not. + +When these credentials are present, **seed a live node so you can test against real data** instead +of stubbing the network: + +```bash +ddev artisan db:seed --class=DevNodeSeeder # a real Proxmox node from the env vars +``` + +`DevNodeSeeder` is idempotent (skips itself when the creds are unset or the node already exists), +so it is safe to run on every fresh sandbox / after `migrate:fresh`. Optional knobs: `PROXMOX_PORT`, +`PROXMOX_VERIFY_TLS`, `PROXMOX_NODE_NAME` (see the seeder's docblock). + +With a node seeded, provision servers to exercise the client/admin UI end-to-end (this clones real +VMs on the node, so it needs the live node above): + +```bash +# SEED_SERVER_USER is an email or user id; SEED_SERVER_COUNT defaults to 10. +ddev exec sh -c 'SEED_SERVER_USER=you@example.com SEED_SERVER_COUNT=3 php artisan db:seed --class=ServerSeeder' +``` + +This is the preferred way to browser-verify frontend work (log in, drive the real screens with a +Playwright/CDP harness) — reach for isolated dev-routes with stubbed responses only when no live +node is available. + +The user may also specify an optional corresponding `$PROXMOX_SSH_TARGET` variable for the +`$PROXMOX_FQDN` in the environment. +If set, you may `ssh $PROXMOX_SSH_TARGET` into the Proxmox node for enhanced testing +(e.g., for cases where using the Proxmox API isn't sufficient). diff --git a/CHANGELOG.md b/CHANGELOG.md index 05e435096d7..edc68196621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,11 @@ follows [Semantic Versioning](https://semver.org) guidelines. scoped route-model binding that the rest of the client API relies on to keep one server's URL from reaching another server's resources. + This describes the 4.x ISO model, in which a row belonged to one node and the same disc on four nodes was four rows. + The library is panel-wide after 4.x: an ISO is offerable on every node, so there is no node boundary left for a mount + request to cross and no relationship for the binding to scope through. The mount and unmount endpoints opt out of + scoping deliberately there, gated on the hidden flag instead, which `RouteScopingTest` records and enforces. + ### Fixed - Fixed servers with no bandwidth limit being incorrectly rate limited to 1 MB/s ([#157](https://github.com/ConvoyPanel/panel/issues/157)). @@ -26,101 +31,6 @@ follows [Semantic Versioning](https://semver.org) guidelines. - Fixed servers with no bandwidth limit being incorrectly rate limited to 1 MB/s ([#157](https://github.com/ConvoyPanel/panel/issues/157)). -## v4.6.0 - -### Changes - -- Published the database port to the loopback interface in `docker-compose.yml` so you can access your database locally without exposing it to the network. -- Convoy will now skip Proxmox configuration tasks when the desired state already matches what's on the node, reducing unnecessary API calls. -- Increased `UpdatePasswordJob` retry attempts to 15 with a 30 second backoff to better survive slow disk resize operations during VM creation. -- Improved bulk IP address range validation to show a descriptive error when the ending address is less than the starting address or the range exceeds 65,536 addresses. - -## v4.6.0-beta - -### Changes - -- Published the database port to the loopback interface in `docker-compose.yml` so you can access your database locally without exposing it to the network. -- Convoy will now skip Proxmox configuration tasks when the desired state already matches what's on the node, reducing unnecessary API calls. -- Increased `UpdatePasswordJob` retry attempts to 15 with a 30 second backoff to better survive slow disk resize operations during VM creation. -- Improved bulk IP address range validation to show a descriptive error when the ending address is less than the starting address or the range exceeds 65,536 addresses. - -## v4.5.1 - -### TIME SENSITIVE SECURITY UPDATE - -Please update immediately to this version to ensure your Convoy installation is secure. - -### Changes - -- Updated vulnerable dependencies -- Additional details are embargoed until a later date - -## v4.5.0 - -### TIME SENSITIVE SECURITY UPDATE - -Please update immediately to this version to ensure your Convoy installation is secure. - -### Changes - -- Updated to Laravel 11 from 10 - -## v4.5.0-rc.1 - -### TIME SENSITIVE SECURITY UPDATE - -Please update immediately to this version to ensure your Convoy installation is secure. - -### Changes - -- Updated to Laravel 11 from 10 - -## v4.4.1 - -### TIME SENSITIVE SECURITY UPDATE - -Please update immediately to this version to ensure your Convoy installation is secure. Details are still pending. - - -## v4.4.0 - -### Changes - -- For security purposes, I disabled publication of database, Redis, and workspace ports in the `docker-compose.yml` file. - -## v4.3.1 - -### Changes - -- Tokens will be revoked when an administrator privileges are removed #132 - -#### From v4.3.0-rc.1 - -- Added guest agent support for changing Windows user passwords #120 - - This feature is still experimental. Please provide feedback on - our [Discord community](https://discord.convoypanel.com/) and report bugs on - our [GitHub - repository](https://github.com/ConvoyPanel/panel/issues). -- Servers will now automatically start after unsuspension #119 -- Fixed parsing of user realm types #126 -- Fixed broken redirect when unauthenticated while accessing certain admin routes #123 -- Fixed fetching of nameservers when there are none present #125 - -## v4.3.0-rc.1 - -> [!IMPORTANT] -> The source between v4 and v10 will begin to diverge starting here. Once v10 is complete, v4's commit history will be -> abandoned. We will not be introducing any changes to the database structure in v4 to prevent any conflicts with v10's -> database structure. - -### Changes - -- Added guest agent support for changing Windows user passwords #120 -- Servers will now automatically start after unsuspension #119 -- Fixed parsing of user realm types #126 -- Fixed broken redirect when unauthenticated while accessing certain admin routes #123 -- Fixed fetching of nameservers when there are none present #125 - ## v4.2.4 ### Changes @@ -686,4 +596,4 @@ Otherwise, your code will error when you send invalid requests. - Editing the server field for IP Addresses will sometime result in the first server of the node to be used. This will be resolved in v3.x.x -![The Bombay cat breed is the mascot for v2](https://imgur.com/fP6oxn9.png) +![The Bombay cat breed is the mascot for v2](https://imgur.com/fP6oxn9.png) \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000000..e9631e73b3e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +See [AGENTS.md](AGENTS.md) for agent instructions. \ No newline at end of file diff --git a/CONTRIBUTOR_LICENSE_AGREEMENT b/CONTRIBUTOR_LICENSE_AGREEMENT index 4b413c2660a..af586ffcb21 100644 --- a/CONTRIBUTOR_LICENSE_AGREEMENT +++ b/CONTRIBUTOR_LICENSE_AGREEMENT @@ -1,66 +1,41 @@ ### Performave Individual Contributor License Agreement -Thank you for your interest in contributing to open source software projects (“Projects”) made available by Performave or its affiliates (“Performave”). This Individual Contributor License Agreement (“Agreement”) sets out the terms governing any source code, object code, bug fixes, configuration changes, tools, specifications, documentation, data, materials, feedback, information or other works of authorship that you submit or have submitted, in any form and in any manner, to Performave in respect of any of the Projects (collectively “Contributions”). If you have any questions respecting this Agreement, please contact eric@performave.com. +Thank you for your interest in contributing to open source or source-available software projects made available under the Performave name (the "Projects"). This Individual Contributor License Agreement (the "Agreement") sets out the terms governing any source code, object code, bug fixes, configuration changes, tools, specifications, documentation, data, materials, feedback, information, or other works of authorship that you submit or have submitted to Eric Wang in respect of any of the Projects (collectively, "Contributions"). +Performave is a project or trade name and is not currently a separate legal entity. For purposes of this Agreement, "Eric Wang," "we," "us," and "our" mean Eric Wang, the individual project steward. If you have questions about this Agreement, please contact eric [at] performave [dot] com. -You agree that the following terms apply to all of your past, present and future Contributions. Except for the licenses granted in this Agreement, you retain all of your right, title and interest in and to your Contributions. +By submitting a Contribution, or by otherwise accepting this Agreement through an approved contribution workflow, you agree that the following terms apply to all of your past, present, and future Contributions. Except for the licenses granted in this Agreement, you retain all right, title, and interest in and to your Contributions. +**Definitions.** "You" and "your" mean the individual who submits a Contribution and accepts this Agreement. "Submit" means any form of electronic, written, or verbal communication sent to us or our representatives for the purpose of discussing, improving, or contributing to a Project, including through source code control systems, issue trackers, pull requests, email, chat, or other project communication channels. A submission is not a Contribution if you clearly mark it in writing as "Not a Contribution." -**Copyright License.** You hereby grant, and agree to grant, to Performave a non-exclusive, perpetual, irrevocable, worldwide, fully-paid, royalty-free, transferable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, and distribute your Contributions and such derivative works, with the right to sublicense the foregoing rights through multiple tiers of sublicensees. +**Eligibility.** You represent that you are at least 18 years old and have the legal capacity to enter into this Agreement. We do not accept Contributions from minors under this Agreement. This Agreement is for individual contributors; Contributions owned by a company, employer, client, school, or other legal entity require separate written permission or a separate contributor agreement signed by an authorized representative of that entity. +**Copyright License.** You hereby grant, and agree to grant, to Eric Wang a non-exclusive, perpetual, irrevocable, worldwide, fully paid, royalty-free, transferable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute, and otherwise use your Contributions and derivative works of your Contributions, with the right to sublicense the foregoing rights through multiple tiers of sublicensees. This license permits us to license Contributions as part of the Projects under any terms we choose. -**Patent License.** You hereby grant, and agree to grant, to Performave a non-exclusive, perpetual, irrevocable, -worldwide, fully-paid, royalty-free, transferable patent license to make, have made, use, offer to sell, sell, -import, and otherwise transfer your Contributions, where such license applies only to those patent claims -licensable by you that are necessarily infringed by your Contributions alone or by combination of your -Contributions with the Project to which such Contributions were submitted, with the right to sublicense the -foregoing rights through multiple tiers of sublicensees. +**Patent License.** You hereby grant, and agree to grant, to Eric Wang a non-exclusive, perpetual, irrevocable, worldwide, fully paid, royalty-free, transferable patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer your Contributions, where such license applies only to those patent claims licensable by you that are necessarily infringed by your Contributions alone or by combination of your Contributions with the Project to which such Contributions were submitted, with the right to sublicense the foregoing rights through multiple tiers of sublicensees. +**Moral Rights.** To the fullest extent permitted under applicable law, you hereby waive, and agree not to assert, all of your moral rights, rights of attribution, rights of integrity, and similar non-economic rights in or relating to your Contributions for the benefit of Eric Wang, his successors and assigns, and their respective direct and indirect sublicensees. If any such rights cannot be waived, you agree not to enforce them against those parties. -**Moral Rights.** To the fullest extent permitted under applicable law, you hereby waive, and agree not to -assert, all of your “moral rights” in or relating to your Contributions for the benefit of Performave, its assigns, and -their respective direct and indirect sublicensees. +**Third-Party Content and Rights.** If your Contribution includes or is based on any material that was not authored by you ("Third-Party Content"), or if you are aware of any third-party intellectual property, proprietary, confidentiality, license, or contractual rights associated with your Contribution ("Third-Party Rights"), you agree to include complete details with your submission. Those details should identify the relevant part of the Contribution, the owner or author of the Third-Party Content or Third-Party Rights, where you obtained it, and any applicable license terms or restrictions. This disclosure obligation does not apply to portions of a Project that are incorporated into your Contribution to that same Project. +**AI-Assisted Contributions.** If you use generative artificial intelligence, code completion, or similar automated tools to create a material part of a Contribution, you represent that you reviewed the Contribution, understand it, and have the right to submit it under this Agreement. You agree to disclose any material use of such tools if required by the Project's contribution guidelines or if the tool output may be subject to third-party rights, license restrictions, confidentiality obligations, or other restrictions. -**Third Party Content/Rights.** If your Contribution includes or is based on any source code, object code, bug -fixes, configuration changes, tools, specifications, documentation, data, materials, feedback, information or -other works of authorship that were not authored by you (“Third Party Content”) or if you are aware of any -third party intellectual property or proprietary rights associated with your Contribution (“Third Party Rights”), -then you agree to include with the submission of your Contribution full details respecting such Third Party -Content and Third Party Rights, including, without limitation, identification of which aspects of your -Contribution contain Third Party Content or are associated with Third Party Rights, the owner/author of the -Third Party Content and Third Party Rights, where you obtained the Third Party Content, and any applicable -third party license terms or restrictions respecting the Third Party Content and Third Party Rights. For greater -certainty, the foregoing obligations respecting the identification of Third Party Content and Third Party Rights -do not apply to any portion of a Project that is incorporated into your Contribution to that same Project. +**Representations.** You represent that, other than any Third-Party Content and Third-Party Rights disclosed by you in accordance with this Agreement: (a) you are the sole author of your Contributions; (b) you are legally entitled to grant the licenses and waivers in this Agreement; (c) your Contributions do not violate any agreement, policy, law, or third-party right known to you; and (d) your Contributions do not include confidential information that you are not authorized to submit. +**Employment and Other Obligations.** If your Contributions were created in the course of your employment, using your employer's resources, or under circumstances where an employer, client, school, or other third party may have rights in them, you represent that you have received permission to submit the Contributions, that the relevant third party has waived any rights that would conflict with this Agreement, or that the relevant third party has no such rights. If you are unsure, do not submit the Contribution until you have obtained appropriate permission. -**Representations.** You represent that, other than the Third Party Content and Third Party Rights identified by -you in accordance with this Agreement, you are the sole author of your Contributions and are legally entitled -to grant the foregoing licenses and waivers in respect of your Contributions. If your Contributions were -created in the course of your employment with your past or present employer(s), you represent that such -employer(s) has authorized you to make your Contributions on behalf of such employer(s) or such employer -(s) has waived all of their right, title or interest in or to your Contributions. +**No Support Obligation; Disclaimer.** You are not required to provide support for your Contributions, except to the extent you choose to do so. To the fullest extent permitted under applicable law, your Contributions are provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of title, non-infringement, merchantability, or fitness for a particular purpose. +**No Obligation to Use Contributions.** You acknowledge that we are under no obligation to use, review, accept, or incorporate your Contributions into any Project. The decision to use or incorporate your Contributions will be made at our sole discretion or by our authorized delegates. -**Disclaimer.** To the fullest extent permitted under applicable law, your Contributions are provided on an "asis" -basis, without any warranties or conditions, express or implied, including, without limitation, any implied -warranties or conditions of non-infringement, merchantability or fitness for a particular purpose. You are not -required to provide support for your Contributions, except to the extent you desire to provide support. +**Notice of Changed Circumstances.** You agree to notify us if you become aware of facts or circumstances that would make any representation in this Agreement inaccurate in any material respect. +**Acceptance and Records.** You may accept this Agreement by signing it, by electronically agreeing to it through an approved contribution workflow, or by submitting a Contribution after being presented with notice that Contributions are governed by this Agreement. You agree that electronic records and electronic signatures may be used to form and evidence this Agreement. We may maintain records of your acceptance, including your name, username, email address, timestamp, repository, pull request, commit information, and the version of this Agreement that you accepted. -**No Obligation.** You acknowledge that Performave is under no obligation to use or incorporate your Contributions -into any of the Projects. The decision to use or incorporate your Contributions into any of the Projects will be -made at the sole discretion of Performave or its authorized delegates. +**Governing Law and Venue.** This Agreement shall be governed by and construed in accordance with the laws of the State of Oklahoma, United States of America, without giving effect to its conflict-of-laws rules, other than rules that direct application of Oklahoma law. The parties consent to venue and personal jurisdiction in the state courts located in Oklahoma County, Oklahoma, and, where federal jurisdiction exists, the United States District Court for the Western District of Oklahoma, for disputes relating to this Agreement. +**Severability.** If any provision of this Agreement is held by a court or other tribunal of competent jurisdiction to be unenforceable, the remaining provisions will remain in full force and effect. -**Disputes.** This Agreement shall be governed by and construed in accordance with the laws of the State of -Oklahoma, United States of America, without giving effect to its principles or rules regarding conflicts of laws, -other than such principles directing application of Oklahoma law. The parties hereby submit to venue in, and -jurisdiction of the courts located in Oklahoma, Oklahoma for purposes relating to this Agreement. In the event -that any of the provisions of this Agreement shall be held by a court or other tribunal of competent jurisdiction -to be unenforceable, the remaining portions hereof shall remain in full force and effect. +**Assignment.** You agree that Eric Wang may assign this Agreement, and all rights, obligations, and licenses under it, to any successor, assignee, or entity that owns, operates, or manages the Projects, provided that the assignee agrees to be bound by this Agreement. - -**Assignment.** You agree that Performave may assign this Agreement, and all of its rights, obligations and licenses -hereunder. +**Entire Agreement.** This Agreement is the entire agreement between you and Eric Wang concerning your Contributions and supersedes any prior or contemporaneous understandings on that subject, except for any separate written agreement signed by you and Eric Wang. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000000..8f92c41302f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,156 @@ +# syntax=docker/dockerfile:1.9 + +# Convoy ships as a single image. The web, queue-worker and scheduler containers +# in compose.yml are all *this* image with different commands -- there is no +# second "compact" image, because the difference between a bundled and an +# external database is which host DB_HOST points at, not which artifact you run. +# +# The base images are serversideup/php (GPL-3.0), pinned by digest so a rebuild +# is reproducible and so we always know exactly which upstream version we are +# redistributing. See NOTICE.md. We add files alongside theirs (docker/entrypoint.d) +# rather than editing their scripts, which keeps our layer clearly separate from +# a copyleft one. + +# Both stages that only produce architecture-independent output (PHP sources and +# compiled JS) are pinned to BUILDPLATFORM: running them once natively instead of +# under emulation is the difference between a 4-minute and a 40-minute arm64 build. +ARG PHP_CLI_IMAGE=serversideup/php:8.4-cli-alpine-v4.5.1@sha256:968edae34d871b593e77e629686d3f664c9a017e6946af19babbe5a5382c2331 +ARG PHP_RUNTIME_IMAGE=serversideup/php:8.4-frankenphp-alpine-v4.5.1@sha256:2e41d837255dae28b5c3ea44a2f0817bab3adc903c9e35e795326608198fdfd7 + +# Alpine's own repositories carry Node 24; CI and ddev both build the frontend +# on Node 22, and the build that ships should be the one that is tested. +ARG NODE_IMAGE=node:22-alpine + +# gmp is load-bearing (Support/Network.php and the address-availability maths run +# on every relevant request) and is NOT in the serversideup default set, which is +# opcache/pcntl/pdo_mysql/pdo_pgsql/redis/zip. The rest mirrors the extension list +# in .github/workflows/tests.yml so the image and CI agree on what PHP looks like. +ARG EXTRA_PHP_EXTENSIONS="gmp bcmath intl pgsql" + +########################################################################## +# Stage 0 -- Node toolchain +########################################################################## +# Only ever used as a source for COPY. Declaring it as a stage is what lets the +# image reference stay an ARG: `COPY --from=${ARG}` is resolved before build +# args are substituted and fails to parse. +FROM --platform=${BUILDPLATFORM} ${NODE_IMAGE} AS node + +########################################################################## +# Stage 1 -- Composer dependencies +########################################################################## +FROM --platform=${BUILDPLATFORM} ${PHP_CLI_IMAGE} AS vendor + +ARG EXTRA_PHP_EXTENSIONS +USER root +RUN install-php-extensions ${EXTRA_PHP_EXTENSIONS} +USER www-data + +WORKDIR /var/www/html + +# Manifests first, so a source-only change does not re-resolve every package. +COPY --chown=www-data:www-data composer.json composer.lock ./ +RUN composer install \ + --no-dev \ + --no-scripts \ + --no-autoloader \ + --prefer-dist \ + --no-interaction \ + --no-progress + +COPY --chown=www-data:www-data . . + +# `composer dump-autoload` fires post-autoload-dump -> `artisan package:discover`, +# which boots the framework. It needs an .env to boot but never a database (the +# release workflow proves this: it builds with no Postgres service). The file is +# removed immediately afterwards so no build-time config survives into the image. +RUN cp .env.example .env \ + && composer dump-autoload --no-dev --optimize --no-interaction \ + && rm -f .env + +########################################################################## +# Stage 2 -- Frontend assets +########################################################################## +# This stage needs PHP as well as Node: `npm run build` runs a `prebuild` hook +# (`artisan typescript:transform` + `artisan wayfinder:generate`), and both of +# those outputs are gitignored, so they cannot be copied in from the context. +FROM --platform=${BUILDPLATFORM} vendor AS assets + +# Node is copied in rather than installed from Alpine's repositories so the +# version matches CI. Both images are musl-based, so the binary is compatible; +# it needs libstdc++, which the CLI variant does not ship by default. +USER root +RUN apk add --no-cache libstdc++ +COPY --from=node /usr/local/bin/node /usr/local/bin/node +COPY --from=node /usr/local/lib/node_modules /usr/local/lib/node_modules +RUN ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \ + && ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx +USER www-data + +WORKDIR /var/www/html + +# The prebuild artisan commands boot the app, so they need an APP_KEY present. +# It is a throwaway: the real key comes from the host .env at runtime. +RUN cp .env.example .env \ + && php artisan key:generate --ansi \ + && npm ci --no-audit --no-fund \ + && npm run build \ + && rm -rf node_modules .env + +########################################################################## +# Stage 3 -- Runtime +########################################################################## +FROM ${PHP_RUNTIME_IMAGE} AS runtime + +ARG EXTRA_PHP_EXTENSIONS +USER root +RUN install-php-extensions ${EXTRA_PHP_EXTENSIONS} + +# Our own entrypoint scripts. Numbered below 50 so they run before serversideup's +# 50-laravel-automations.sh -- the storage skeleton has to exist before +# `storage:link` and the first log write, and a missing APP_KEY should be a clear +# error rather than a 500 on the login page. +COPY --chmod=755 docker/entrypoint.d/ /etc/entrypoint.d/ +USER www-data + +ENV APP_ENV=production \ + APP_DEBUG=false \ + # There is no log file to tail in a container. Laravel's default `stack` + # channel writes to storage/logs; stderr puts everything in `docker logs` + # alongside Caddy's own output. Raise to debug when chasing something. + LOG_CHANNEL=stderr \ + LOG_LEVEL=info \ + # Laravel's health route (bootstrap/app.php, health: '/up'). The image default + # is /healthcheck, which Caddy answers itself without ever touching PHP -- a + # container that reports healthy while the app is broken is worse than none. + HEALTHCHECK_PATH=/up \ + # Off by default upstream; an unconfigured opcache is the single most common + # reason a containerised Laravel app is inexplicably slow. + PHP_OPCACHE_ENABLE=1 \ + # The application code in this image is immutable, so there is nothing to + # revalidate. Compiled Blade views are written once at boot, before the + # server starts accepting requests. + PHP_OPCACHE_VALIDATE_TIMESTAMPS=0 \ + PHP_OPCACHE_MAX_ACCELERATED_FILES=20000 \ + PHP_MEMORY_LIMIT=512M \ + # Automations are opted into per-service in compose.yml: exactly one container + # may run migrations, and the worker/scheduler must not race it. + AUTORUN_ENABLED=false + +WORKDIR /var/www/html + +COPY --from=assets --chown=www-data:www-data /var/www/html /var/www/html + +# Stamped the same way the release workflow stamps a tarball build. The pattern +# matches whatever version is currently committed rather than a literal +# 'canary', so the stamp cannot silently no-op when that value is changed. +ARG CONVOY_VERSION=canary +RUN sed -i "s/'version' => '[^']*',/'version' => '${CONVOY_VERSION}',/" config/app.php \ + && grep -q "'version' => '${CONVOY_VERSION}'," config/app.php + +LABEL org.opencontainers.image.title="Convoy" \ + org.opencontainers.image.description="KVM server management panel for hosting businesses." \ + org.opencontainers.image.url="https://convoypanel.com" \ + org.opencontainers.image.source="https://github.com/ConvoyPanel/panel" \ + org.opencontainers.image.documentation="https://docs.convoypanel.com" \ + org.opencontainers.image.vendor="Performave" \ + org.opencontainers.image.version="${CONVOY_VERSION}" diff --git a/LICENSE.md b/LICENSE.md index aa0a7890512..60ffb3e08af 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,124 +1,141 @@ -# Convoy Software End User License Agreement (EULA) +# Convoy Software End User License Agreement -**Effective Date:** March 3th, 2024 +**Effective Date:** March 3, 2024 -**Last Updated:** March 13th, 2024 +**Last Updated:** July 7, 2026 -**License Grantor:** Performave +**Licensor:** Eric Wang, operating under the Performave name -## 1. Acceptance of Terms +**Contact:** eric@performave.com -By installing, copying, downloading, accessing, or otherwise using the Convoy Panel software ("Software"), you agree to -be bound by the terms of this End User License Agreement ("EULA"). If you do not agree to the terms of this EULA, do not -install or use the Software. +**Website:** https://convoypanel.com -## 2. License Grant +This End User License Agreement ("Agreement") governs your access to and use of the Convoy Panel software, including its source code, object code, documentation, updates, and related materials (collectively, the "Software"). By downloading, installing, copying, modifying, distributing, accessing, or using the Software, you agree to this Agreement. If you do not agree, do not use the Software. -### 2.1 Personal Use License +Performave is a project or trade name and is not currently a separate legal entity. For purposes of this Agreement, "Eric Wang," "Licensor," "we," "us," and "our" mean Eric Wang, the individual project steward. -Performave grants you a non-exclusive, non-transferable, free license to download, install, and use the Software for -personal, non-commercial purposes, provided that you comply with all the terms and conditions of this EULA. +## 1. License Types -### 2.2 Enterprise License +### 1.1 Personal and Hobby Community License -If you wish to use the Software for commercial purposes, including but not limited to production environments, business -operations, or any activity intended for profit, you must subscribe to an Enterprise License. The Enterprise License is -subscription-based, and the fees are based on the number of nodes on which the Software is used. The specific terms, -including the fee structure and the number of nodes allowed, will be determined at the time of the subscription. Each -license permits the use of the Software on the number of nodes paid for and is non-transferable. +Subject to this Agreement, Licensor grants you a limited, non-exclusive, non-transferable, revocable, royalty-free license to download, install, copy, modify, and use the Software for personal, non-commercial use. -### 2.3 Non-Profit Organization License +Personal, non-commercial use includes homelab use and non-commercial hobby or community projects, including projects that receive voluntary donations, sponsorships, or similar community support, so long as the Software is not used to provide paid services, operate a business, support revenue-generating activity, or otherwise obtain a commercial advantage. -Non-profit organizations, upon providing proof of 501(c)(3) registration or its equivalent, are granted a non-exclusive, -non-transferable license to use the Software for free. The Software may be used for the organization's operational -purposes, subject to the terms and conditions of this EULA. +### 1.2 Commercial License -### 2.4 Partnership Licenses +Any Commercial Use of the Software requires a paid commercial license from Licensor. "Commercial Use" means use of the Software in connection with paid services, business operations, revenue-generating activity, customer-facing services, internal operations of a for-profit business, or any other activity intended to produce commercial advantage. -Licenses obtained through partnerships or negotiations with Performave are valid as per the agreements made during such -negotiations. These licenses are subject to the specific terms agreed upon and must also adhere to the general terms and -conditions of this EULA. +Commercial licenses are granted only under a separate written agreement, subscription, order form, invoice, or other written authorization from Licensor. Commercial license fees and usage limits may be based on the number of nodes, features, support level, deployment scope, term length, or other terms agreed at the time of purchase. -### 2.5 Insider License +Unless the applicable commercial license states otherwise, each commercial license is non-transferable and permits use of the Software only within the scope, term, node count, and other limits stated in the applicable written authorization. -Performave may grant an Insider License to individuals recruited specifically for testing new versions or features of -the Software. This license includes a waiver of fees associated with the use of the Software during the testing period. -Testers are expected to be available to test the Software as required and provide feedback to Performave. Performave -reserves the right to revoke this license at any time at its discretion, including for lack of participation or if the -tester's needs no longer align with the testing program's objectives. +### 1.3 Nonprofit and Special Licenses -## 3. Legal Use Requirement +Nonprofit, educational, charitable, community, partner, sponsored, or other special licenses are granted only on a case-by-case basis through written authorization from Licensor. Any such license is subject to this Agreement unless the written authorization states otherwise. -You agree to use the Software only for lawful purposes and in compliance with all applicable laws and regulations. Any -use of the Software for illegal or criminal activities is strictly prohibited. Performave reserves the right to -terminate your license if you engage in any illegal conduct with the Software. In the event of such termination, -Performave isn't obligated to refund any transactions. +### 1.4 Insider and Testing Licenses + +Licensor may grant an Insider, beta, preview, testing, or similar license to individuals or organizations for testing new versions, features, or deployments of the Software. Unless otherwise stated in writing, these licenses are temporary, non-transferable, royalty-free, and limited to evaluation and testing purposes. + +Testers may be expected to provide feedback and participate in testing activities. Licensor may revoke an Insider or testing license at any time, including for lack of participation, misuse, expiration of a testing program, or a change in Licensor's testing needs. + +## 2. Modifications and Forks + +You may modify the Software and create derivative works, subject to this Agreement. + +You may distribute modified versions or forks of the Software only if all of the following conditions are met: + +- The modified version is licensed to recipients under this Agreement. +- You preserve copyright, license, attribution, and source notices included with the Software. +- You clearly identify the modified version as modified, unofficial, and not endorsed by Licensor. +- You do not imply that the modified version is an official Convoy or Performave release. +- You do not remove, disable, bypass, obscure, or interfere with licensing, entitlement, attribution, update, or license enforcement mechanisms, except as expressly permitted in writing by Licensor. +- You do not sell, sublicense, rent, lease, or otherwise grant commercial use rights to the Software or any modified version. + +Distribution of a modified version does not grant any recipient a commercial license. Any Commercial Use of the Software, including Commercial Use of a fork or modified version, requires a paid commercial license from Licensor. + +## 3. Redistribution + +You may redistribute unmodified copies of the Software, including through package managers, container registries, installers, mirrors, or similar distribution channels, if you preserve all copyright, license, attribution, and source notices and do not imply that you are Licensor or an official distributor unless Licensor has authorized you in writing. + +Redistribution does not grant commercial use rights. Any Commercial Use by you or a recipient requires a paid commercial license from Licensor. ## 4. Restrictions -The following restrictions apply to your use of the Software, but these are not all-inclusive. Additional restrictions -may also apply as outlined elsewhere in this EULA or as otherwise determined by Performave: +Except as expressly permitted by this Agreement or by written authorization from Licensor, you may not: + +- Use the Software for Commercial Use without a valid commercial license. +- Remove, alter, or obscure copyright, license, attribution, or proprietary notices. +- Remove, disable, bypass, tamper with, or interfere with any licensing, entitlement, node-count, subscription, update, or license enforcement mechanism. +- Misrepresent modified versions, forks, packages, builds, or services as official Convoy or Performave releases. +- Use the Software in a way that violates applicable law or regulation. +- Use the Software to provide unlawful, abusive, fraudulent, harmful, or unauthorized services. +- Use the Software in a way that damages, disables, overburdens, or impairs Licensor's systems or interferes with another party's use of Licensor's services. +- Sublicense or sell rights to use the Software except as expressly permitted in writing by Licensor. + +## 5. License Enforcement + +The Software may include license validation, entitlement checks, node-count checks, subscription checks, usage checks, update checks, and other license enforcement mechanisms. + +These mechanisms may verify license validity, commercial entitlement, subscription status, expiration, non-payment, node count, deployment scope, feature access, and suspected tampering or circumvention. If a license is invalid, expired, unpaid, exceeded, revoked, or suspected of being tampered with or circumvented, the Software may restrict, suspend, or disable access to some or all functionality. + +You may not remove, disable, bypass, tamper with, or interfere with these mechanisms without Licensor's prior written permission. Licensor is not responsible for loss, damage, interruption, or inconvenience caused by license enforcement actions taken in good faith to protect the Software, enforce this Agreement, or enforce a commercial license, to the fullest extent permitted by law. + +## 6. Contributions + +Contributions to the Software are governed by the repository's `CONTRIBUTOR_LICENSE_AGREEMENT`, unless Licensor has agreed to different contribution terms in writing. This Agreement governs use of the Software and does not replace the contribution license terms accepted by contributors. + +## 7. Intellectual Property and Branding + +The Software is licensed, not sold. Licensor and its licensors retain all right, title, and interest in and to the Software, including all copyrights, trade secrets, and other intellectual property rights. All rights not expressly granted are reserved. + +This Agreement does not grant you any trademark, service mark, trade name, logo, branding, domain name, or similar rights in "Convoy," "Convoy Panel," "Performave," or related names or marks. You may use those names only as necessary to make truthful, non-misleading references to the Software, including to state that a fork or modified version is derived from Convoy Panel, provided that you clearly identify it as unofficial and not endorsed by Licensor. + +## 8. Third-Party Software + +The Software may include or depend on third-party software, packages, libraries, assets, or services that are governed by separate license terms. Those third-party terms apply to the applicable third-party materials. Nothing in this Agreement limits rights you may have under third-party licenses. + +## 9. Termination -- You may not modify the Software in a manner that interferes with its licensing mechanism or changes its copyright - information without making substantial other modifications. -- You are permitted to modify the Software for your personal or enterprise use to tailor it to your needs, provided such - modifications do not violate the restrictions stated in this EULA. -- You may not distribute or sublicense modified versions of the Software that violate the terms of this EULA. -- You may not use the Software in any manner that could damage, disable, overburden, or impair any Performave server, or - the network(s) connected to any Performave server, or interfere with any other party's use and enjoyment of the - Software. +This Agreement is effective until terminated. Your rights under this Agreement terminate automatically if you violate this Agreement or exceed the scope of your license. -### 4.1 Additional Licensing Terms for Modifications and Contributions +Upon termination, you must stop using the Software and destroy all copies of the Software in your possession or control, except that you may retain archival copies solely as required by law or for ordinary backup retention, provided that those copies are not used or restored except as permitted by a valid license. -Any modifications, enhancements, derivative works of the Software, or any code from the Software that is incorporated into other works by you or any third party are considered part of the Software and subject to the terms and conditions of this EULA. Such modifications, derivative works, or incorporated code must be offered under the same terms and conditions as those set forth in this EULA, including any provisions regarding distribution and sublicensing. You may not alter the terms of this EULA or sublicense any modifications, derivative works, or incorporated code under terms that differ from those specified in this EULA. +Termination does not limit Licensor's other rights or remedies. Sections that by their nature should survive termination will survive, including restrictions, intellectual property rights, disclaimers, limitations of liability, governing law, and payment obligations. -## 5. License Enforcement and Digital Rights Management +## 10. Updates and Changes to This Agreement -Performave employs various measures, including Digital Rights Management (DRM), to enforce the terms of this EULA and prevent unauthorized use of the Software. These measures may include, but are not limited to, remotely disabling access to the Software or specific features of the Software for users who are found to be in violation of this EULA. By using the Software, you acknowledge and agree that Performave may, at its sole discretion, implement such measures. +Licensor may update this Agreement from time to time. Updated terms apply to new downloads, new installations, new versions, updates, renewals, and commercial licenses issued after the updated terms are posted or otherwise provided. -You further agree that Performave shall not be responsible or liable for any loss, damage, or inconvenience you may suffer as a result of such actions taken to enforce this EULA. Your rights under this EULA may be subject to termination and denial of access to the Software without notice if any form of tampering with or circumvention of the DRM or other license enforcement mechanisms is detected. +Unless required by a separate written agreement or applicable law, updated terms do not retroactively change the license terms for a copy of the Software you previously received. If you download, install, update, or continue using a version provided with updated terms, you accept the updated terms for that version. -This section is designed to inform users of the license enforcement practices and to legally protect Performave from liability for actions taken in good faith to protect its intellectual property rights. +## 11. Disclaimer of Warranty -## 6. Intellectual Property Rights +THE SOFTWARE IS PROVIDED "AS IS" AND "AS AVAILABLE," WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND. TO THE FULLEST EXTENT PERMITTED BY LAW, LICENSOR DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, INCLUDING WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, QUIET ENJOYMENT, NON-INFRINGEMENT, ACCURACY, RELIABILITY, SECURITY, AND AVAILABILITY. -The Software is protected by intellectual property laws and treaties. Performave or its suppliers own all title, -copyright, and interest in and to the Software, including any intellectual property rights therein. This EULA grants you -no rights to use such content. All rights not expressly granted are reserved by Performave. +## 12. Limitation of Liability -## 7. Termination +TO THE FULLEST EXTENT PERMITTED BY LAW, LICENSOR WILL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, EXEMPLARY, PUNITIVE, OR SIMILAR DAMAGES; LOSS OF PROFITS; LOSS OF REVENUE; LOSS OF DATA; BUSINESS INTERRUPTION; COMPUTER DAMAGE; SYSTEM FAILURE; SERVICE INTERRUPTION; OR COST OF SUBSTITUTE GOODS OR SERVICES ARISING OUT OF OR RELATED TO THE SOFTWARE, THIS AGREEMENT, OR ANY LICENSE ENFORCEMENT ACTION, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -This EULA is effective until terminated. Your rights under this EULA will terminate automatically without notice from -Performave if you fail to comply with any term(s) of this EULA. Upon termination, you shall cease all use of the -Software and destroy all copies, full or partial, of the Software. +TO THE FULLEST EXTENT PERMITTED BY LAW, LICENSOR'S TOTAL LIABILITY ARISING OUT OF OR RELATED TO THE SOFTWARE OR THIS AGREEMENT WILL NOT EXCEED THE AMOUNT YOU PAID TO LICENSOR FOR THE SOFTWARE DURING THE TWELVE MONTHS BEFORE THE EVENT GIVING RISE TO LIABILITY, OR USD $100 IF YOU PAID NOTHING. -## 8. Disclaimer of Warranty +## 13. Governing Law and Venue -The Software is provided "AS IS," with all faults, without warranty of any kind, and Performave hereby disclaims all -warranties and conditions with respect to the Software, either express, implied, or statutory, including, but not -limited to, the implied warranties and/or conditions of merchantability, of satisfactory quality, of fitness for a -particular purpose, of accuracy, of quiet enjoyment, and non-infringement of third-party rights. +This Agreement is governed by and construed in accordance with the laws of the State of Oklahoma, United States of America, without giving effect to its conflict-of-laws rules, other than rules that direct application of Oklahoma law. -## 9. Limitation of Liability +The parties consent to venue and personal jurisdiction in the state courts located in Oklahoma County, Oklahoma, and, where federal jurisdiction exists, the United States District Court for the Western District of Oklahoma, for disputes relating to this Agreement. -In no event shall Performave be liable for any indirect, incidental, special, consequential, or punitive damages -whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business -information, or any other pecuniary loss) arising out of the use of or inability to use the Software, even if Performave -has been advised of the possibility of such damages. +## 14. Notices and Commercial License Requests -## 10. Governing Law +Commercial license requests, questions, and notices may be sent to eric@performave.com or through https://convoypanel.com. -This EULA shall be governed by the laws of the jurisdiction in which Performave is located, without reference to -conflict of laws principles. +## 15. Entire Agreement -## 11. Entire Agreement +This Agreement, together with any applicable commercial license, order form, written authorization, or contribution agreement, is the entire agreement between you and Licensor concerning your use of the Software and supersedes all prior or contemporaneous understandings concerning that subject. -This EULA constitutes the entire agreement between you and Performave relating to the Software and supersedes all prior -or contemporaneous oral or written communications, proposals, and representations with respect to the Software or any -other subject matter covered by this EULA. +If there is a conflict between this Agreement and a separate written commercial license, order form, or written authorization signed or otherwise approved by Licensor, the separate written terms control for the subject matter of that conflict. -## 12. Amendment +## 16. Severability -Performave reserves the right to amend this EULA at any time, at its sole discretion, by posting an updated version to -its website or through the Software. Your continued use of the Software following the posting of an updated EULA will -mean that you accept those changes. +If any provision of this Agreement is held unenforceable, the remaining provisions will remain in full force and effect, and the unenforceable provision will be interpreted or replaced to the maximum extent permitted by law to preserve its intended effect. diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 00000000000..c64e454570a --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,46 @@ +# Third-party notices + +Convoy itself is proprietary and licensed under the terms in `LICENSE.md`. The +container image published from this repository additionally contains the +third-party components below, each under its own license. Those licenses govern +those components only: they are aggregated with Convoy on the same image, not +combined with it, and nothing here changes the license of Convoy's own code. + +## serversideup/php + +The image's base layers are `serversideup/php`, which provides the PHP runtime +configuration, the container entrypoint, the s6-overlay process supervision and +the Caddy/FrankenPHP web server configuration. + +- Project: +- License: GPL-3.0-or-later +- Versions used: see the `PHP_CLI_IMAGE` and `PHP_RUNTIME_IMAGE` arguments at the + top of `Dockerfile`, which pin both the release tag and the content digest. + +These components are redistributed **unmodified**. Complete corresponding source +for the exact version in any image we publish is available at the project URL +above, at the release tag recorded in the `Dockerfile`. Requests for source may +also be sent to the address in `LICENSE.md`. + +Convoy adds files alongside these components (`docker/entrypoint.d/`) rather than +editing them. If that ever changes, the modified files must be published under +GPL-3.0-or-later — keep customisations in our own files. + +## Other components + +The image also contains, from the upstream layers it is built on: + +| Component | License | +| --- | --- | +| PHP | PHP License v3.01 | +| FrankenPHP | MIT | +| Caddy | Apache-2.0 | +| s6-overlay | ISC | +| Alpine Linux base system and packages | various — run `apk info --license -a` in the image for the per-package list | +| musl libc | MIT | +| Composer dependencies | see `composer.lock` | +| npm dependencies (compiled into `public/build`) | see `package-lock.json` | + +The services referenced by `compose.yml` — PostgreSQL (PostgreSQL License) and +Redis (AGPLv3, or RSALv2/SSPLv1 at your option) — are pulled directly from their +own publishers at run time and are not redistributed as part of Convoy's image. diff --git a/README.md b/README.md index b39dbdd1809..3f902e6db3a 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![Version 4 release announcement banner](https://github.com/ConvoyPanel/panel/assets/37554696/4629321b-7214-4eb1-8cc5-85c89229b5bf) -![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/convoypanel/panel/tests.yml?branch=develop) +![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/convoypanel/panel/tests.yml?branch=main) ![Discord](https://img.shields.io/discord/746612878261616700?label=Discord&logo=Discord&logoColor=white) ![GitHub Releases](https://img.shields.io/github/downloads/convoypanel/panel/latest/total) @@ -18,6 +18,32 @@ Stop paying hundreds of dollars for unreliable and slow software. Subscribe to a - [Panel Documentation](https://docs.convoypanel.com) - [Discord Community](https://discord.convoypanel.com) +## Installation + +Convoy installs onto a dedicated host with one command: + +```bash +curl -fsSL https://install.convoypanel.com | sudo bash +``` + +See [docs/deployment.md](docs/deployment.md) for requirements, TLS, upgrades and +running against an external database, and [docs/configuration.md](docs/configuration.md) +for every supported setting. + +## Local Development + +Local dev runs on [ddev](https://ddev.com) (Postgres 17): + +```bash +ddev start +ddev composer install +ddev artisan migrate +ddev npm install && ddev npm run build # or: ddev npm run dev for HMR +``` + +The app is served at https://convoy.ddev.site. See [AGENTS.md](AGENTS.md) for details on +running Artisan/Composer/npm, regenerating typed frontend artifacts, and database snapshots. + ## Acknowledgements Please [visit this page](https://convoypanel.com/docs/project/about.html#acknowledgements) on our website to view acknowledgements. diff --git a/app/Actions/Auth/ConfigureCeremonyStepManagerFactoryAction.php b/app/Actions/Auth/ConfigureCeremonyStepManagerFactoryAction.php new file mode 100644 index 00000000000..5679b7b751d --- /dev/null +++ b/app/Actions/Auth/ConfigureCeremonyStepManagerFactoryAction.php @@ -0,0 +1,37 @@ +environment('local') && config('app.version') === 'canary') { + $csmFactory->setSecuredRelyingPartyId(['localhost']); + } + + return $csmFactory; + } +} diff --git a/app/Actions/Auth/DisableAuthenticator.php b/app/Actions/Auth/DisableAuthenticator.php new file mode 100644 index 00000000000..6266284081d --- /dev/null +++ b/app/Actions/Auth/DisableAuthenticator.php @@ -0,0 +1,27 @@ +two_factor_secret) && is_null($user->two_factor_confirmed_at)) { + return; + } + + $user->forceFill([ + 'two_factor_secret' => null, + 'two_factor_confirmed_at' => null, + 'two_factor_recovery_codes' => $user->passkeys()->exists() + ? $user->two_factor_recovery_codes + : null, + ])->save(); + + TwoFactorAuthenticationDisabled::dispatch($user); + } +} diff --git a/app/Actions/Auth/EnableAuthenticator.php b/app/Actions/Auth/EnableAuthenticator.php new file mode 100644 index 00000000000..9b4bfc99b05 --- /dev/null +++ b/app/Actions/Auth/EnableAuthenticator.php @@ -0,0 +1,45 @@ +two_factor_secret) || $force === true) { + // Fortify's contract still declares this method without arguments, + // while its concrete provider accepts the configured secret length + // and Fortify's own action passes it. The application binding is + // that concrete provider; make the current package contract explicit + // until its interface catches up with its implementation. + /** @var TwoFactorAuthenticationProvider $provider */ + $provider = $this->provider; + + $attributes = [ + 'two_factor_secret' => Fortify::currentEncrypter()->encrypt( + $provider->generateSecretKey( + (int) config('fortify-options.two-factor-authentication.secret-length', 16), + ), + ), + ]; + + if (empty($user->two_factor_recovery_codes)) { + $attributes['two_factor_recovery_codes'] = Fortify::currentEncrypter()->encrypt( + json_encode(Collection::times(8, fn () => RecoveryCode::generate())->all()), + ); + } + + $user->forceFill($attributes)->save(); + + TwoFactorAuthenticationEnabled::dispatch($user); + } + } +} diff --git a/app/Actions/Auth/GeneratePasskeyAuthenticationOptionsAction.php b/app/Actions/Auth/GeneratePasskeyAuthenticationOptionsAction.php new file mode 100644 index 00000000000..ae33c5613e4 --- /dev/null +++ b/app/Actions/Auth/GeneratePasskeyAuthenticationOptionsAction.php @@ -0,0 +1,41 @@ +toJson($options); + } +} diff --git a/app/Actions/Auth/GeneratePasskeyRegisterOptionsAction.php b/app/Actions/Auth/GeneratePasskeyRegisterOptionsAction.php new file mode 100644 index 00000000000..010d427893b --- /dev/null +++ b/app/Actions/Auth/GeneratePasskeyRegisterOptionsAction.php @@ -0,0 +1,17 @@ +validateCredentials($request); + + if ($user?->hasEnabledSecondFactor()) { + return $this->twoFactorChallengeResponse($request, $user); + } + + return $next($request); + } +} diff --git a/app/Actions/Auth/StorePasskeyAction.php b/app/Actions/Auth/StorePasskeyAction.php new file mode 100644 index 00000000000..751648c952d --- /dev/null +++ b/app/Actions/Auth/StorePasskeyAction.php @@ -0,0 +1,156 @@ +determinePublicKeyCredentialSource( + $passkeyJson, + $passkeyOptionsJson, + $hostName, + ); + + /** @var Passkey $passkey */ + $passkey = $authenticatable->passkeys()->create([ + 'name' => $this->defaultName($authenticatable, $publicKeyCredentialSource), + ...$additionalProperties, + 'data' => $publicKeyCredentialSource, + ]); + + event(new PasskeyRegisteredEvent($passkey, $authenticatable)); + + return $passkey; + } + + /** + * Name the passkey after whatever created it — "1Password", "iCloud Keychain", "YubiKey 5 + * Series" — so the account settings list reads sensibly even if the user never renames it. + * Authenticators we can't identify (unknown or all-zero AAGUID) fall back to a datestamp. + * + * Registering a second passkey from the same authenticator gets a counter suffix, since the + * name is all the list has to tell two entries apart. + */ + protected function defaultName( + HasPasskeys $authenticatable, + PublicKeyCredentialSource $publicKeyCredentialSource, + ): string { + $authenticator = AuthenticatorAaguids::nameFor($publicKeyCredentialSource->aaguid); + + if ($authenticator === null) { + return 'Passkey '.now()->format('Y-m-d'); + } + + $taken = $authenticatable->passkeys()->pluck('name')->all(); + $name = $authenticator; + + for ($suffix = 2; in_array($name, $taken, true); $suffix++) { + $name = Str::limit($authenticator, Passkey::NAME_MAX_LENGTH - strlen(" ($suffix)"), '')." ($suffix)"; + } + + return $name; + } + + protected function determinePublicKeyCredentialSource( + string $passkeyJson, + string $passkeyOptionsJson, + string $hostName, + ): PublicKeyCredentialSource { + $passkeyOptions = $this->getPasskeyOptions($passkeyOptionsJson); + + $publicKeyCredential = $this->getPasskey($passkeyJson); + + if (! $publicKeyCredential->response instanceof AuthenticatorAttestationResponse) { + throw new InvalidPasskeyPublicKeyCredential; + } + + $configureCeremonyStepManagerFactory = Config::getAction( + 'configure_ceremony_step_manager_factory', + ConfigureCeremonyStepManagerFactoryAction::class, + ); + $creationCsm = $configureCeremonyStepManagerFactory->execute()->creationCeremony(); + + try { + $publicKeyCredentialSource = AuthenticatorAttestationResponseValidator::create($creationCsm)->check( + authenticatorAttestationResponse: $publicKeyCredential->response, + publicKeyCredentialCreationOptions: $passkeyOptions, + host: $hostName, + ); + } catch (Throwable $exception) { + throw new InvalidAuthenticatorAttestationResponse($exception); + } + + return CredentialRecordConverter::toPublicKeyCredentialSource($publicKeyCredentialSource); + } + + protected function getPasskeyOptions(string $passkeyOptionsJson): PublicKeyCredentialCreationOptions + { + if (! json_validate($passkeyOptionsJson)) { + throw new InvalidPasskeyJson; + } + + /** @var PublicKeyCredentialCreationOptions $passkeyOptions */ + $passkeyOptions = Serializer::make()->fromJson( + $passkeyOptionsJson, + PublicKeyCredentialCreationOptions::class, + ); + + return $passkeyOptions; + } + + protected function getPasskey(string $passkeyJson): PublicKeyCredential + { + if (! json_validate($passkeyJson)) { + throw new InvalidPasskeyJson; + } + + /** @var PublicKeyCredential $publicKeyCredential */ + $publicKeyCredential = Serializer::make()->fromJson( + $passkeyJson, + PublicKeyCredential::class, + ); + + return $publicKeyCredential; + } +} diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php deleted file mode 100644 index bc1aa5b9a6a..00000000000 --- a/app/Actions/Fortify/CreateNewUser.php +++ /dev/null @@ -1,35 +0,0 @@ - ['required', 'string', 'max:255'], - 'email' => [ - 'required', - 'string', - 'email', - 'max:255', - Rule::unique(User::class), - ], - 'password' => $this->passwordRules(), - ])->validate(); - - return User::create([ - 'name' => $input['name'], - 'email' => $input['email'], - 'password' => Hash::make($input['password']), - ]); - } -} diff --git a/app/Actions/Fortify/PasswordValidationRules.php b/app/Actions/Fortify/PasswordValidationRules.php deleted file mode 100644 index 5be4df1eabd..00000000000 --- a/app/Actions/Fortify/PasswordValidationRules.php +++ /dev/null @@ -1,16 +0,0 @@ - $this->passwordRules(), - ])->validate(); - - $user->forceFill([ - 'password' => Hash::make($input['password']), - ])->save(); - } -} diff --git a/app/Actions/Fortify/UpdateUserPassword.php b/app/Actions/Fortify/UpdateUserPassword.php deleted file mode 100644 index f87582534d2..00000000000 --- a/app/Actions/Fortify/UpdateUserPassword.php +++ /dev/null @@ -1,31 +0,0 @@ - ['required', 'string', 'current_password:web'], - 'password' => $this->passwordRules(), - ], [ - 'current_password.current_password' => __('The provided password does not match your current password.'), - ])->validateWithBag('updatePassword'); - - $user->forceFill([ - 'password' => Hash::make($input['password']), - ])->save(); - } -} diff --git a/app/Actions/Fortify/UpdateUserProfileInformation.php b/app/Actions/Fortify/UpdateUserProfileInformation.php deleted file mode 100644 index 331e65f911e..00000000000 --- a/app/Actions/Fortify/UpdateUserProfileInformation.php +++ /dev/null @@ -1,57 +0,0 @@ - ['required', 'string', 'max:255'], - - 'email' => [ - 'required', - 'string', - 'email', - 'max:255', - Rule::unique('users')->ignore($user->id), - ], - ])->validateWithBag('updateProfileInformation'); - - if ($input['email'] !== $user->email && - $user instanceof MustVerifyEmail) { - $this->updateVerifiedUser($user, $input); - } else { - $user->forceFill([ - 'name' => $input['name'], - 'email' => $input['email'], - ])->save(); - } - } - - /** - * Update the given verified user's profile information. - * - * @param mixed $user - */ - protected function updateVerifiedUser($user, array $input): void - { - $user->forceFill([ - 'name' => $input['name'], - 'email' => $input['email'], - 'email_verified_at' => null, - ])->save(); - - $user->sendEmailVerificationNotification(); - } -} diff --git a/app/Actions/Ipam/GenerateAddressesAction.php b/app/Actions/Ipam/GenerateAddressesAction.php new file mode 100644 index 00000000000..6a2576febf2 --- /dev/null +++ b/app/Actions/Ipam/GenerateAddressesAction.php @@ -0,0 +1,137 @@ +isSparse()) { + return new GeneratedAddressesData( + createdCount: 0, + remaining: 0, + isComplete: true, + sparse: true, + ); + } + + $fromPrefix = $addressBlock->prefix_length_from; + $toPrefix = $addressBlock->prefix_length_to; + $baseIp = $addressBlock->base_ip; + + $allAddresses = $addressBlock->version === AddressVersion::IPv4 + ? $this->calculateIPv4Subnets($baseIp, $fromPrefix, $toPrefix) + : $this->calculateIPv6Subnets($baseIp, $fromPrefix, $toPrefix); + + $existing = $addressBlock->addresses()->pluck('ip')->toArray(); + $toCreate = array_diff($allAddresses, $existing); + $batchToCreate = array_slice($toCreate, 0, self::BATCH_SIZE); + + // Network / broadcast / gateway are materialized but auto-reserved so they're never allocated. + $systemReserved = array_flip($addressBlock->systemReservedAddresses()); + + // Prepare data for batch insert + $insertData = []; + foreach ($batchToCreate as $ip) { + $insertData[] = [ + 'address_block_id' => $addressBlock->id, + 'server_id' => null, + 'ip' => $ip, + 'prefix_length' => $toPrefix, + 'state' => isset($systemReserved[$ip]) + ? AddressState::Reserved->value + : AddressState::Available->value, + 'state_reason' => isset($systemReserved[$ip]) + ? AddressStateReason::System->value + : null, + ]; + } + + if (! empty($insertData)) { + $addressBlock->addresses()->insert($insertData); + } + + $createdCount = count($insertData); + $remainingCount = count($toCreate) - $createdCount; + $isComplete = $remainingCount <= 0; + + return new GeneratedAddressesData( + createdCount: $createdCount, + remaining: $remainingCount, + isComplete: $isComplete, + ); + } + + private function calculateIPv4Subnets(string $baseIp, int $fromPrefix, int $toPrefix): array + { + $baseAddr = ip2long($baseIp); + $baseMask = ~((1 << (32 - $fromPrefix)) - 1); + $networkAddr = $baseAddr & $baseMask; + $hostBits = 32 - $toPrefix; + $subnetIncrement = 1 << $hostBits; + $numSubnets = 1 << ($toPrefix - $fromPrefix); + $addresses = []; + for ($i = 0; $i < $numSubnets; $i++) { + $subnetAddr = $networkAddr + ($i * $subnetIncrement); + $addresses[] = long2ip($subnetAddr); + } + + return $addresses; + } + + private function calculateIPv6Subnets(string $baseIp, int $fromPrefix, int $toPrefix): array + { + $binaryIp = inet_pton($baseIp); + if ($binaryIp === false) { + throw new \InvalidArgumentException('Invalid IPv6 address'); + } + $binaryIp = $this->applyIpv6Mask($binaryIp, $fromPrefix); + $bitDiff = $toPrefix - $fromPrefix; + // Dense v6 blocks are bounded by AddressBlock::DENSE_MAX_HOST_BITS (isSparse() already + // returned early for anything larger), so this loop is capped at 2^16 iterations. + $numSubnets = 1 << $bitDiff; + $addresses = []; + for ($i = 0; $i < $numSubnets; $i++) { + $newBinaryIp = $binaryIp; + for ($bit = 0; $bit < $bitDiff; $bit++) { + $bytePos = intdiv($fromPrefix + $bit, 8); + $bitPos = ($fromPrefix + $bit) % 8; + if (($i >> $bit) & 1) { + $newBinaryIp[$bytePos] = chr(ord($newBinaryIp[$bytePos]) | (1 << (7 - $bitPos))); + } else { + $newBinaryIp[$bytePos] = chr(ord($newBinaryIp[$bytePos]) & ~(1 << (7 - $bitPos))); + } + } + $addresses[] = inet_ntop($newBinaryIp); + } + + return $addresses; + } + + private function applyIpv6Mask(string $binaryIp, int $prefixLength): string + { + $result = $binaryIp; + for ($i = 0; $i < 16; $i++) { + $bitPos = $i * 8; + if ($bitPos >= $prefixLength) { + $result[$i] = chr(0); + } elseif ($bitPos + 8 > $prefixLength) { + $bitsToKeep = $prefixLength - $bitPos; + $mask = ~((1 << (8 - $bitsToKeep)) - 1) & 0xFF; + $result[$i] = chr(ord($result[$i]) & $mask); + } + } + + return $result; + } +} diff --git a/app/Actions/Server/BuildServerAction.php b/app/Actions/Server/BuildServerAction.php new file mode 100644 index 00000000000..3326980fe36 --- /dev/null +++ b/app/Actions/Server/BuildServerAction.php @@ -0,0 +1,144 @@ +onStart($deployment), + $this->getJobs($deployment, $accountPassword), + $this->onComplete($deployment), + ]); + + $deployment->server->update(['lifecycle' => ServerLifecycle::INSTALLING]); + + Bus::chain($jobs) + ->catch($this->onFail($deployment)) + ->dispatch(); + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function getJobs(Deployment $deployment, ?string $accountPassword): array + { + if ($deployment->type === DeploymentType::INSTALL || $deployment->type === DeploymentType::REINSTALL) { + $jobs = $this->createInstallStepsAndJobs($deployment); + } else { + $jobs = $this->createConfigureStepsAndJobs($deployment); + } + + return $this->appendOptionalJobs($deployment, $accountPassword, $jobs); + } + + /** + * Both sizes come out of the panel's own records. + * + * This used to open a connection to the node and read the template's config + * just to size a progress bar. There is no template to read any more, and + * the image version already knows both figures -- what has to be + * transferred, and what the imported disk will occupy -- so a build no + * longer needs the node to be reachable before it can be queued. + */ + private function createInstallStepsAndJobs(Deployment $deployment): array + { + $version = $deployment->imageVersion; + + $steps = $deployment->addSteps([ + [ + 'name' => 'fetch-image', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::DETERMINATE, + 'progress_total' => (int) $version->size, + ], + [ + 'name' => 'import', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::DETERMINATE, + 'progress_total' => $version->minimumDiskSize(), + ], + [ + 'name' => 'configure', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::INDETERMINATE, + ], + ]); + + return [ + new FetchImageJob($steps[0]), + new ImportVmJob($steps[1]), + new ConfigureVmJob($steps[2]), + ]; + } + + private function createConfigureStepsAndJobs(Deployment $deployment): array + { + $step = $deployment->addSteps([ + [ + 'name' => 'configure', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::INDETERMINATE, + ], + ])[0]; + + return [ + new ConfigureVmJob($step), + ]; + } + + private function appendOptionalJobs( + Deployment $deployment, + ?string $accountPassword, + array $jobs, + ): array { + if (filled($accountPassword)) { + $step = $deployment->addSteps([ + [ + 'name' => 'update-password', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::INDETERMINATE, + ], + ])[0]; + $jobs[] = new UpdatePasswordJob($step, $accountPassword); + } + + if ($deployment->start_on_completion) { + $step = $deployment->addSteps([ + [ + 'name' => 'start-vm', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::INDETERMINATE, + ], + ])[0]; + $jobs[] = new SendPowerCommandJob($step, PowerCommand::START); + } + + return $jobs; + } +} diff --git a/app/Actions/Server/DeleteServerAction.php b/app/Actions/Server/DeleteServerAction.php new file mode 100644 index 00000000000..855af720db1 --- /dev/null +++ b/app/Actions/Server/DeleteServerAction.php @@ -0,0 +1,84 @@ +addSteps([ + [ + 'name' => 'delete-backups', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::DETERMINATE, + 'progress_total' => $deployment->server->backups() + ->whereNull('error_code') + ->whereNotNull('completed_at') + ->count() * 2, // 2 jobs for each backup: purge and monitor + ], + ])[0]; + + $jobs = Arr::flatten([ + Bus::batch(new BatchPurgeServerBackupsJob($deployment->server)) + ->before(function () use ($step) { + $step->markRunning(); + }) + ->progress(function (Batch $batch) use ($step) { + $step->update(['progress_current' => max($batch->processedJobs() - 1, 0)]); + }) + ->then(function () use ($step) { + $step->markCompleted(); + }) + ->catch(function (Batch $_, Throwable $e) use ($step) { + $step->markFailed($e); + }), + $this->getJobs($deployment), + function () use ($deployment) { + $deployment->server->delete(); + }, + ]); + + $deployment->server->update(['lifecycle' => ServerLifecycle::DELETING]); + + Bus::chain($jobs) + ->catch($this->onFail($deployment, ServerLifecycle::DELETION_FAILED)) + ->dispatch(); + + } + + public function getJobs(Deployment $deployment): array + { + $steps = $deployment->addSteps([ + [ + 'name' => 'stop-vm', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::INDETERMINATE, + ], + [ + 'name' => 'delete-vm', + 'status' => DeploymentStatus::PENDING, + 'progress_mode' => ProgressMode::INDETERMINATE, + ], + ]); + + return [ + new StopVmJob($steps[0]), + new DeleteVmJob($steps[1]), + ]; + } +} diff --git a/app/Actions/Server/RebuildServerAction.php b/app/Actions/Server/RebuildServerAction.php new file mode 100644 index 00000000000..4081e709900 --- /dev/null +++ b/app/Actions/Server/RebuildServerAction.php @@ -0,0 +1,41 @@ +onStart($deployment), + $this->deleteServerAction->getJobs($deployment), + $this->buildServerAction->getJobs($deployment, $accountPassword), + $this->onComplete($deployment), + ]); + + $deployment->server->update(['lifecycle' => ServerLifecycle::INSTALLING]); + + Bus::chain($jobs) + ->catch($this->onFail($deployment)) + ->dispatch(); + } +} diff --git a/app/Auth/IdentityConfirmation.php b/app/Auth/IdentityConfirmation.php new file mode 100644 index 00000000000..f7f610d625e --- /dev/null +++ b/app/Auth/IdentityConfirmation.php @@ -0,0 +1,45 @@ +put(self::SESSION_KEY, now()->timestamp); + } + + public static function isConfirmed(Session $session): bool + { + return self::expiresIn($session) > 0; + } + + /** Seconds left on the current confirmation; 0 when there is none. */ + public static function expiresIn(Session $session): int + { + $confirmedAt = $session->get(self::SESSION_KEY); + + if (! is_int($confirmedAt)) { + return 0; + } + + return max(0, $confirmedAt + self::WINDOW - now()->timestamp); + } +} diff --git a/app/Auth/Socialite/OidcProvider.php b/app/Auth/Socialite/OidcProvider.php new file mode 100644 index 00000000000..3e6a999df94 --- /dev/null +++ b/app/Auth/Socialite/OidcProvider.php @@ -0,0 +1,166 @@ + + */ + protected $scopes = ['openid', 'profile', 'email']; + + protected $scopeSeparator = ' '; + + /** + * Cached discovery document for this request lifecycle. + * + * @var array|null + */ + protected ?array $discovery = null; + + protected function getAuthUrl($state): string + { + return $this->buildAuthUrlFromBase($this->endpoint('authorization_endpoint'), $state); + } + + protected function getTokenUrl(): string + { + return $this->endpoint('token_endpoint'); + } + + /** + * {@inheritdoc} + */ + protected function getUserByToken($token): array + { + $response = $this->getHttpClient()->get($this->endpoint('userinfo_endpoint'), [ + RequestOptions::HEADERS => [ + 'Accept' => 'application/json', + 'Authorization' => 'Bearer '.$token, + ], + ]); + + return json_decode((string) $response->getBody(), true) ?: []; + } + + /** + * {@inheritdoc} + * + * Maps the standard OIDC claims. `email_verified` is kept in the raw payload so + * OAuthAuthenticationService can gate auto-link/provision on it. + */ + protected function mapUserToObject(array $user): User + { + return (new User)->setRaw($user)->map([ + 'id' => Arr::get($user, 'sub'), + 'nickname' => Arr::get($user, 'preferred_username'), + 'name' => Arr::get($user, 'name'), + 'email' => Arr::get($user, 'email'), + 'avatar' => Arr::get($user, 'picture'), + ]); + } + + /** + * Resolve a protocol endpoint, preferring an explicit `config/services.php` override + * and otherwise reading it from the cached discovery document. + */ + protected function endpoint(string $key): string + { + $override = $this->getConfig($this->overrideKey($key)); + + if (filled($override)) { + return (string) $override; + } + + $value = Arr::get($this->discover(), $key); + + if (! filled($value)) { + throw new RuntimeException( + "OIDC discovery for issuer \"{$this->getConfig('base_url')}\" is missing \"{$key}\"." + ); + } + + return (string) $value; + } + + /** + * The `config/services.php` key that pins a given discovery endpoint explicitly. + */ + protected function overrideKey(string $discoveryKey): string + { + return match ($discoveryKey) { + 'authorization_endpoint' => 'auth_url', + 'token_endpoint' => 'token_url', + 'userinfo_endpoint' => 'userinfo_url', + default => $discoveryKey, + }; + } + + /** + * Fetch and cache the IdP's discovery document. Cached for an hour keyed by issuer so a + * login flurry doesn't hammer the IdP's well-known endpoint. + * + * @return array + */ + protected function discover(): array + { + if (is_array($this->discovery)) { + return $this->discovery; + } + + $issuer = rtrim((string) $this->getConfig('base_url'), '/'); + + if ($issuer === '') { + throw new RuntimeException('OIDC provider requires a "base_url" (issuer) in config/services.php.'); + } + + return $this->discovery = Cache::remember( + 'oidc.discovery:'.md5($issuer), + now()->addHour(), + function () use ($issuer): array { + $response = $this->getHttpClient()->get($issuer.'/.well-known/openid-configuration', [ + RequestOptions::HEADERS => ['Accept' => 'application/json'], + ]); + + $document = json_decode((string) $response->getBody(), true); + + if (! is_array($document)) { + throw new RuntimeException("OIDC discovery at issuer \"{$issuer}\" returned an invalid document."); + } + + return $document; + } + ); + } + + /** + * Read a value from this driver's `config/services.php` block. Socialite's manager only + * hands the constructor the client id/secret/redirect, so anything extra (issuer, scopes, + * endpoint overrides) is read straight from config here. + */ + protected function getConfig(string $key): mixed + { + return config("services.oidc.{$key}"); + } +} diff --git a/app/Casts/MebibytesToAndFromBytes.php b/app/Casts/MebibytesToAndFromBytes.php deleted file mode 100644 index f84a591bbd7..00000000000 --- a/app/Casts/MebibytesToAndFromBytes.php +++ /dev/null @@ -1,25 +0,0 @@ -decrypt($value) : null; + return ! empty($value) ? app(Encrypter::class)->decrypt($value) : null; } /** @@ -25,6 +25,6 @@ public function get(Model $model, string $key, mixed $value, array $attributes): */ public function set(Model $model, string $key, mixed $value, array $attributes): ?string { - return !empty($value) ? app(Encrypter::class)->encrypt($value) : null; + return ! empty($value) ? app(Encrypter::class)->encrypt($value) : null; } } diff --git a/app/Casts/OveragePenaltyCast.php b/app/Casts/OveragePenaltyCast.php new file mode 100644 index 00000000000..14322db4390 --- /dev/null +++ b/app/Casts/OveragePenaltyCast.php @@ -0,0 +1,38 @@ +|null> + */ +class OveragePenaltyCast implements CastsAttributes +{ + public function get(Model $model, string $key, mixed $value, array $attributes): ?OveragePenaltyData + { + if ($value === null) { + return null; + } + + return OveragePenaltyData::from(json_decode($value, true)); + } + + public function set(Model $model, string $key, mixed $value, array $attributes): ?string + { + if ($value === null) { + return null; + } + + $penalty = $value instanceof OveragePenaltyData + ? $value + : OveragePenaltyData::from($value); + + return $penalty->toJson(); + } +} diff --git a/app/Casts/StorageSizeCast.php b/app/Casts/StorageSizeCast.php new file mode 100644 index 00000000000..7b8f6c28eda --- /dev/null +++ b/app/Casts/StorageSizeCast.php @@ -0,0 +1,55 @@ += 0 ? $value * 1048576 : -1; // Convert from megabytes to bytes + } + + /** + * Prepare the given value for storage. + */ + public function set(Model $model, string $key, mixed $value, array $attributes): ?int + { + if ($value === null) { + return null; + } + + return $value >= 0 ? intval( + floor($value / 1048576), + ) : -1; // Convert from bytes to megabytes to prevent overflow + } +} diff --git a/app/Console/Commands/Anchor/PollAnchorLivenessCommand.php b/app/Console/Commands/Anchor/PollAnchorLivenessCommand.php new file mode 100644 index 00000000000..31b7b6ee52a --- /dev/null +++ b/app/Console/Commands/Anchor/PollAnchorLivenessCommand.php @@ -0,0 +1,69 @@ +subMinutes(AnchorProtocol::STATUS_TTL_MINUTES); + + /* + * Only installations that are enrolled but have stopped reporting are + * worth probing: a fresh heartbeat already tells us everything a probe + * would, and one that never enrolled has no secret we could trust. + * + * Machines still in `anchor_enrollments` are deliberately not probed -- + * nobody has told us an address to probe them at, and that is what + * approval establishes. + */ + $stale = Node::query() + ->whereNotNull('agent_enrolled_at') + ->where(fn ($query) => $query + ->whereNull('agent_last_seen_at') + ->orWhere('agent_last_seen_at', '<', $cutoff)) + ->get() + ->concat( + Relay::query() + ->whereNotNull('enrolled_at') + ->where(fn ($query) => $query + ->whereNull('last_seen_at') + ->orWhere('last_seen_at', '<', $cutoff)) + ->get() + ); + + if ($stale->isEmpty()) { + $this->info('No Anchors need probing.'); + + return Command::SUCCESS; + } + + $this->info('Probing Anchors with a stale heartbeat.'); + + $stale->each(function (Node|Relay $installation) use ($liveness) { + (new Task($this->output))->render( + "Anchor {$installation->anchorName()}", + fn () => $liveness->refresh($installation), + ); + }); + + return Command::SUCCESS; + } +} diff --git a/app/Console/Commands/Maintenance/CheckForUpdatesCommand.php b/app/Console/Commands/Maintenance/CheckForUpdatesCommand.php new file mode 100644 index 00000000000..4eff4442505 --- /dev/null +++ b/app/Console/Commands/Maintenance/CheckForUpdatesCommand.php @@ -0,0 +1,56 @@ +check(); + } catch (UpdateCheckFailedException $exception) { + // The previous result is deliberately left in the cache, so the + // admin area keeps showing the last version it heard about. + $this->error($exception->getMessage()); + + return self::FAILURE; + } + + match ($status->status) { + UpdateStatus::UPDATE_AVAILABLE => $this->warn( + "An update is available: {$status->latestVersion} (running {$status->currentVersion}).", + ), + UpdateStatus::UP_TO_DATE => $this->info( + "The panel is up to date ({$status->currentVersion}).", + ), + // A source checkout has no release to compare itself against, but + // the fetch still happened, so record what the latest release is. + UpdateStatus::UNKNOWN => $this->info( + "Latest published release is {$status->latestVersion}; this panel does not report a release version.", + ), + }; + + return self::SUCCESS; + } +} diff --git a/app/Console/Commands/Maintenance/PruneAuditLogsCommand.php b/app/Console/Commands/Maintenance/PruneAuditLogsCommand.php new file mode 100644 index 00000000000..3f47db1b2e6 --- /dev/null +++ b/app/Console/Commands/Maintenance/PruneAuditLogsCommand.php @@ -0,0 +1,64 @@ +option('prune-days') ?? config('audit.prune_days'); + + if (! $days || ! is_numeric($days) || $days <= 0) { + throw new InvalidArgumentException('The "--prune-days" option must be a value greater than 0.'); + } + + $days = (int) $days; + $threshold = now()->subDays($days); + $chunk = max(1, (int) config('audit.prune_chunk', 1000)); + + // Security events (authentication, credential and token lifecycle) are exempt — they are + // the reason the log exists and are far too low-volume to be worth reclaiming. + $retained = array_map(fn (AuditEvent $event) => $event->value, AuditEvent::retainedForever()); + + $deleted = 0; + + // Deleted in chunks so a long-neglected install does not issue one enormous statement, and + // by explicit id list because Postgres has no DELETE ... LIMIT. + do { + $ids = AuditLog::query() + ->where('created_at', '<=', $threshold) + ->whereNotIn('event', $retained) + ->limit($chunk) + ->pluck('id'); + + if ($ids->isEmpty()) { + break; + } + + $deleted += AuditLog::query()->whereIn('id', $ids)->delete(); + } while ($ids->count() === $chunk); + + if ($deleted === 0) { + $this->info('There are no audit log entries old enough to prune.'); + + return; + } + + $this->info("Pruned {$deleted} audit log entries older than {$days} days."); + } +} diff --git a/app/Console/Commands/Maintenance/PruneDeploymentsCommand.php b/app/Console/Commands/Maintenance/PruneDeploymentsCommand.php new file mode 100644 index 00000000000..629d5fb1788 --- /dev/null +++ b/app/Console/Commands/Maintenance/PruneDeploymentsCommand.php @@ -0,0 +1,106 @@ +markStuckDeploymentsAsFailed(); + $this->pruneOldDeployments(); + } + + private function markStuckDeploymentsAsFailed(): void + { + $stuckAge = $this->option('stuck-age') ?? config('deployments.stuck_age', 1440); + + if (! $stuckAge || ! is_numeric($stuckAge)) { + return; + } + + $stuckAge = (int) $stuckAge; + $threshold = now()->subMinutes($stuckAge); + + // Measure staleness from when the deployment actually started running, + // not when it was requested — a queue backlog should not trip the + // timeout before the work has had a chance to begin. Older rows without + // a started_at fall back to requested_at. + $stuckDeploymentsQuery = Deployment::query() + ->where('status', DeploymentStatus::RUNNING) + ->whereRaw('COALESCE(started_at, requested_at) <= ?', [$threshold]); + + $count = $stuckDeploymentsQuery->count(); + + if ($count > 0) { + $this->info("Marking {$count} stuck deployments as failed."); + + $stuckDeploymentsQuery->chunk(100, function ($deployments) { + $deploymentIds = $deployments->pluck('id')->toArray(); + $serverIds = $deployments->pluck('server_id')->unique()->toArray(); + + // Mark running steps as failed + DeploymentStep::query() + ->whereIn('deployment_id', $deploymentIds) + ->where('status', DeploymentStatus::RUNNING) + ->update([ + 'status' => DeploymentStatus::FAILED, + 'completed_at' => now(), + 'error_message' => 'Deployment timed out.', + ]); + + // Mark deployments as failed + Deployment::query() + ->whereIn('id', $deploymentIds) + ->update([ + 'status' => DeploymentStatus::FAILED, + 'completed_at' => now(), + ]); + + // Mark servers that are stuck in installing as install_failed + Server::query() + ->whereIn('id', $serverIds) + ->where('lifecycle', ServerLifecycle::INSTALLING) + ->update([ + 'lifecycle' => ServerLifecycle::INSTALL_FAILED, + ]); + }); + } else { + $this->info('No stuck deployments found.'); + } + } + + private function pruneOldDeployments(): void + { + $retentionPeriod = $this->option('retention-period') ?? config('deployments.retention_period', 90); + + if (! $retentionPeriod || ! is_numeric($retentionPeriod)) { + return; + } + + $retentionPeriod = (int) $retentionPeriod; + $threshold = now()->subDays($retentionPeriod); + + $query = Deployment::query() + ->where('requested_at', '<=', $threshold); + + $count = $query->count(); + + if ($count > 0) { + $this->warn("Pruning {$count} deployments older than {$retentionPeriod} days."); + $query->delete(); + } else { + $this->info('No old deployments to prune.'); + } + } +} diff --git a/app/Console/Commands/Maintenance/PruneOrphanedBackupsCommand.php b/app/Console/Commands/Maintenance/PruneOrphanedBackupsCommand.php index d0c31a4fe9d..2ac0684eae3 100644 --- a/app/Console/Commands/Maintenance/PruneOrphanedBackupsCommand.php +++ b/app/Console/Commands/Maintenance/PruneOrphanedBackupsCommand.php @@ -1,36 +1,41 @@ option('prune-age') ?? config('backups.prune_age', 360); - if (! $since || ! is_int($since)) { + + if (! $since || ! is_numeric($since)) { throw new InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.'); } - $query = $repository->getBuilder() + $since = (int) $since; + $threshold = now()->subMinutes($since); + + $query = Backup::query() ->whereNull('completed_at') - ->where('created_at', '<=', CarbonImmutable::now()->subMinutes($since)->toDateTimeString()); + ->where('created_at', '<=', $threshold); $count = $query->count(); + if (! $count) { $this->info('There are no orphaned backups to be marked as failed.'); @@ -39,10 +44,11 @@ public function handle(BackupRepository $repository): void $this->warn("Marking {$count} backups that have not been marked as completed in the last {$since} minutes as failed."); + // Bulk update bypasses model casts, so store the enum's raw value. $query->update([ - 'is_successful' => false, - 'completed_at' => CarbonImmutable::now(), - 'updated_at' => CarbonImmutable::now(), + 'error_code' => BackupErrorCode::TIMEOUT->value, + 'error_message' => 'Backup did not complete in time and was marked as failed.', + 'completed_at' => now(), ]); } } diff --git a/app/Console/Commands/Maintenance/PruneUsersCommand.php b/app/Console/Commands/Maintenance/PruneUsersCommand.php index 1c9b8a31d33..cc3092fc944 100644 --- a/app/Console/Commands/Maintenance/PruneUsersCommand.php +++ b/app/Console/Commands/Maintenance/PruneUsersCommand.php @@ -1,10 +1,10 @@ each(function (Node $node) { (new Task($this->output))->render("Node {$node->fqdn}", function () use ($node) { PruneUsersJob::dispatch($node->id); + + return true; }); }); diff --git a/app/Console/Commands/Maintenance/RefreshAuthenticatorAaguidsCommand.php b/app/Console/Commands/Maintenance/RefreshAuthenticatorAaguidsCommand.php new file mode 100644 index 00000000000..ccc4d9a63de --- /dev/null +++ b/app/Console/Commands/Maintenance/RefreshAuthenticatorAaguidsCommand.php @@ -0,0 +1,226 @@ +fetchFidoMetadata(), ...$this->fetchPasskeyProviders()]; + } catch (RuntimeException $exception) { + $this->error($exception->getMessage()); + + return self::FAILURE; + } + + $names = array_filter( + $names, + fn (string $name) => $name !== '' && ! in_array($name, self::REJECT, true), + ); + + if ($names === []) { + $this->error('Both sources came back empty; refusing to overwrite the table.'); + + return self::FAILURE; + } + + // Sort by name so the generated file diffs readably: a new authenticator shows up as one + // added line next to its siblings, rather than wherever its AAGUID happens to sort. + uksort($names, fn (string $a, string $b) => [mb_strtolower($names[$a]), $a] <=> [mb_strtolower($names[$b]), $b]); + + // Not a given: the very first run generates the table from nothing. + AuthenticatorAaguids::forget(); + $this->reportChanges(file_exists(AuthenticatorAaguids::TABLE) ? AuthenticatorAaguids::names() : [], $names); + + if ($this->option('dry-run')) { + $this->comment('Dry run — the table was left alone.'); + + return self::SUCCESS; + } + + file_put_contents(AuthenticatorAaguids::TABLE, $this->render($names)); + AuthenticatorAaguids::forget(); + + $this->info(count($names).' authenticators written to '.AuthenticatorAaguids::TABLE.'.'); + + return self::SUCCESS; + } + + /** + * @return array + */ + private function fetchFidoMetadata(): array + { + $blob = $this->get(self::FIDO_MDS_URL); + + // An unencrypted JWT: header.payload.signature, each base64url. We only want the payload, + // and deliberately don't verify the signature — see the class docblock. + $segments = explode('.', trim($blob)); + + if (count($segments) !== 3) { + throw new RuntimeException('The FIDO metadata blob was not a JWT.'); + } + + $payload = json_decode( + base64_decode(strtr($segments[1], '-_', '+/'), true) ?: '', + associative: true, + ); + + if (! is_array($payload['entries'] ?? null)) { + throw new RuntimeException('The FIDO metadata blob carried no entries.'); + } + + $names = []; + + foreach ($payload['entries'] as $entry) { + // Entries for UAF/U2F authenticators carry no AAGUID; they can't produce a passkey. + $aaguid = $entry['aaguid'] ?? null; + $description = $entry['metadataStatement']['description'] ?? null; + + if (is_string($aaguid) && is_string($description)) { + $names[mb_strtolower($aaguid)] = AuthenticatorAaguids::displayName($description); + } + } + + $this->line(count($names).' authenticators from the FIDO Metadata Service.'); + + return $names; + } + + /** + * @return array + */ + private function fetchPasskeyProviders(): array + { + $providers = json_decode($this->get(self::PASSKEY_PROVIDERS_URL), associative: true); + + if (! is_array($providers) || $providers === []) { + throw new RuntimeException('The passkey provider list could not be read.'); + } + + $names = []; + + foreach ($providers as $aaguid => $provider) { + if (is_string($provider['name'] ?? null)) { + $names[mb_strtolower($aaguid)] = AuthenticatorAaguids::displayName($provider['name']); + } + } + + $this->line(count($names).' authenticators from the community passkey provider list.'); + + return $names; + } + + private function get(string $url): string + { + $response = Http::timeout(60)->get($url); + + if ($response->failed()) { + throw new RuntimeException("Could not fetch {$url} (HTTP {$response->status()})."); + } + + return $response->body(); + } + + /** + * @param array $before + * @param array $after + */ + private function reportChanges(array $before, array $after): void + { + foreach (array_diff_key($after, $before) as $aaguid => $name) { + $this->info(" + {$name} ({$aaguid})"); + } + + foreach (array_diff_key($before, $after) as $aaguid => $name) { + $this->warn(" - {$name} ({$aaguid})"); + } + + foreach (array_intersect_key($before, $after) as $aaguid => $name) { + if ($after[$aaguid] !== $name) { + $this->comment(" ~ {$name} -> {$after[$aaguid]} ({$aaguid})"); + } + } + + if ($before === $after) { + $this->line('No changes.'); + } + } + + /** + * @param array $names + */ + private function render(array $names): string + { + $rows = ''; + + foreach ($names as $aaguid => $name) { + $rows .= sprintf(" '%s' => '%s',\n", $aaguid, str_replace(['\\', "'"], ['\\\\', "\\'"], $name)); + } + + return <<getName()}` — do not edit by hand. + * + * Maps a WebAuthn authenticator's AAGUID onto a name worth showing a person. Read + * through App\\Support\\Passkeys\\AuthenticatorAaguids, which is where the surrounding + * behaviour (and the reason this is vendored rather than fetched) is documented. + * + * An AAGUID only looks like a UUID — it is 16 opaque bytes, so several of these keys + * are not valid RFC 4122 (Proton Pass's is the ASCII "ProtonPassProton"). + */ + + return [ + {$rows}]; + + PHP; + } +} diff --git a/app/Console/Commands/Maintenance/RefreshJobSignaturesCommand.php b/app/Console/Commands/Maintenance/RefreshJobSignaturesCommand.php new file mode 100644 index 00000000000..9c6df931284 --- /dev/null +++ b/app/Console/Commands/Maintenance/RefreshJobSignaturesCommand.php @@ -0,0 +1,94 @@ +info('Job signatures are up to date ('.count($current).' jobs).'); + + return self::SUCCESS; + } + + if ($this->option('check')) { + $this->error('The job signature snapshot is out of date. Run `php artisan maintenance:refresh-job-signatures` and review the diff.'); + + return self::FAILURE; + } + + file_put_contents(QueuedJobSignatures::SNAPSHOT, $this->render($current)); + + $this->info('Wrote '.count($current).' job signatures. Review the diff before committing — a removed or renamed parameter strands whatever is already on the queue.'); + + return self::SUCCESS; + } + + /** + * @param array>> $signatures + */ + private function render(array $signatures): string + { + $body = ''; + + foreach ($signatures as $class => $parameters) { + $body .= ' '.var_export($class, true)." => [\n"; + + foreach ($parameters as $parameter) { + $pairs = []; + + foreach ($parameter as $key => $value) { + $pairs[] = var_export($key, true).' => '.var_export($value, true); + } + + $body .= ' ['.implode(', ', $pairs)."],\n"; + } + + $body .= " ],\n"; + } + + return <<enabled()) { + $this->info('VictoriaMetrics is not configured; skipping metrics snapshot.'); + + return; + } + + $metrics->writeNow($overview->snapshotMetrics()); + + $this->info('Recorded overview metrics snapshot.'); + } +} diff --git a/app/Console/Commands/Node/PollNodeStatusesCommand.php b/app/Console/Commands/Node/PollNodeStatusesCommand.php new file mode 100644 index 00000000000..747b3d0815d --- /dev/null +++ b/app/Console/Commands/Node/PollNodeStatusesCommand.php @@ -0,0 +1,36 @@ +info('Queuing node status polls.'); + + Node::query()->each(function (Node $node) { + (new Task($this->output))->render("Node {$node->fqdn}", function () use ($node) { + PollNodeStatusJob::dispatch($node->id); + + return true; + }); + }); + + return Command::SUCCESS; + } +} diff --git a/app/Console/Commands/Server/ResetUsagesCommand.php b/app/Console/Commands/Server/ResetUsagesCommand.php index dcc0fc82aa3..ba2573adecd 100644 --- a/app/Console/Commands/Server/ResetUsagesCommand.php +++ b/app/Console/Commands/Server/ResetUsagesCommand.php @@ -1,31 +1,52 @@ update([ - 'bandwidth_usage' => 0, - ]); - } + $now = now(); + $today = $now->day; + $daysInMonth = $now->daysInMonth; + + // COALESCE(bandwidth_reset_day, day-of-created_at): the effective anchor. + $anchor = 'COALESCE(bandwidth_reset_day, EXTRACT(DAY FROM created_at))'; + + $count = Server::query() + ->where(function (Builder $query) use ($anchor, $today, $daysInMonth) { + $query->whereRaw("{$anchor} = ?", [$today]); + + // On the last day of the month, also sweep anchors that never + // occur this month (29–31 in short months). + if ($today === $daysInMonth) { + $query->orWhereRaw("{$anchor} > ?", [$daysInMonth]); + } + }) + ->update(['bandwidth_usage' => 0]); + + $this->info("Reset bandwidth usage for {$count} server(s)."); } } diff --git a/app/Console/Commands/Server/UpdateRateLimitsCommand.php b/app/Console/Commands/Server/UpdateRateLimitsCommand.php index 2cfdc7b7512..ed5f4c21612 100644 --- a/app/Console/Commands/Server/UpdateRateLimitsCommand.php +++ b/app/Console/Commands/Server/UpdateRateLimitsCommand.php @@ -1,11 +1,13 @@ info('Queuing rate limits sync request.'); + $this->info('Queuing rate limit sync.'); - $nodes = Node::all(); - - $nodes->each(function (Node $node) { + Node::all()->each(function (Node $node) { (new Task($this->output))->render("Node {$node->fqdn}", function () use ($node) { - SyncServerRateLimitsJob::dispatch($node->id); + $jobs = $node->servers + ->map(fn (Server $server) => new SyncServerRateLimitJob($server)) + ->all(); + + if ($jobs === []) { + return true; + } + + // One batch per node: servers sync concurrently, failures are + // isolated per server, and the batch stays observable in Horizon. + Bus::batch($jobs) + ->name("Sync rate limits for node #{$node->id}") + ->allowFailures() + ->dispatch(); + + return true; }); }); diff --git a/app/Console/Commands/Server/UpdateUsagesCommand.php b/app/Console/Commands/Server/UpdateUsagesCommand.php index 42b6d77ca25..38c811d4531 100644 --- a/app/Console/Commands/Server/UpdateUsagesCommand.php +++ b/app/Console/Commands/Server/UpdateUsagesCommand.php @@ -1,10 +1,10 @@ each(function (Node $node) { (new Task($this->output))->render("Node {$node->fqdn}", function () use ($node) { SyncServerUsagesJob::dispatch($node->id); + + return true; }); }); diff --git a/app/Console/Commands/User/MakeUserCommand.php b/app/Console/Commands/User/MakeUserCommand.php index e5927689f69..9f993f9c3e9 100644 --- a/app/Console/Commands/User/MakeUserCommand.php +++ b/app/Console/Commands/User/MakeUserCommand.php @@ -23,39 +23,82 @@ SOFTWARE. */ -namespace Convoy\Console\Commands\User; +namespace App\Console\Commands\User; -use Exception; -use Convoy\Models\User; +use App\Exceptions\Model\DataValidationException; +use App\Models\User; use Illuminate\Console\Command; -use Illuminate\Support\Facades\Hash; -use Convoy\Exceptions\Model\DataValidationException; +use Illuminate\Support\Facades\Validator; + +use function Laravel\Prompts\confirm; +use function Laravel\Prompts\password; +use function Laravel\Prompts\text; class MakeUserCommand extends Command { protected $description = 'Creates a user on the system via the CLI.'; - protected $signature = 'c:user:make {--email=} {--name=} {--password=} {--admin=}'; + protected $signature = 'users:create + {--email= : Email address} + {--name= : Name} + {--password= : Password} + {--admin= : Whether the user is an administrator (true/false)}'; /** * Handle command request to create a new user. - * - * @throws Exception - * @throws DataValidationException */ - public function handle(): void + public function handle(): int { - $root_admin = $this->option('admin') ?? $this->confirm('Is this user an administrator?'); - $email = $this->option('email') ?? $this->ask('Email Address'); - $name = $this->option('name') ?? $this->ask('Name'); - $password = $this->option('password') ?? $this->secret('Password'); - - $user = User::create([ - 'name' => $name, - 'email' => $email, - 'root_admin' => (bool) $root_admin, - 'password' => Hash::make($password), - ]); + $rootAdmin = $this->rootAdmin(); + + if ($rootAdmin === null) { + $this->components->error('The --admin option must be a boolean value: true, false, 1, or 0.'); + + return self::FAILURE; + } + + $data = [ + 'email' => $this->option('email') ?? text( + label: 'Email Address', + required: true, + validate: fn (string $value) => $this->validationError('email', $value), + ), + 'name' => $this->option('name') ?? text( + label: 'Name', + required: true, + validate: fn (string $value) => $this->validationError('name', $value), + ), + 'password' => $this->option('password') ?? password( + label: 'Password', + required: true, + ), + 'root_admin' => $rootAdmin, + ]; + + $validator = Validator::make($data, $this->rules()); + + if ($validator->fails()) { + foreach ($validator->errors()->all() as $error) { + $this->components->error($error); + } + + return self::FAILURE; + } + + try { + $user = User::create([ + 'name' => $data['name'], + 'email' => $data['email'], + 'root_admin' => $data['root_admin'], + 'password' => $data['password'], + ]); + } catch (DataValidationException $exception) { + foreach ($exception->getMessageBag()->all() as $error) { + $this->components->error($error); + } + + return self::FAILURE; + } $this->table(['Field', 'Value'], [ ['Internal ID', $user->id], @@ -63,5 +106,44 @@ public function handle(): void ['Name', $user->name], ['Admin', $user->root_admin ? 'Yes' : 'No'], ]); + + return self::SUCCESS; + } + + private function rootAdmin(): ?bool + { + $admin = $this->option('admin'); + + if ($admin === null) { + return confirm('Is this user an administrator?'); + } + + if ($admin === '') { + return null; + } + + return filter_var($admin, FILTER_VALIDATE_BOOL, FILTER_NULL_ON_FAILURE); + } + + /** + * @return array + */ + private function rules(): array + { + $rules = User::getRules(); + + return [ + 'email' => $rules['email'], + 'name' => $rules['name'], + 'password' => ['required', 'string'], + 'root_admin' => $rules['root_admin'], + ]; + } + + private function validationError(string $field, string $value): ?string + { + $validator = Validator::make([$field => $value], [$field => $this->rules()[$field]]); + + return $validator->errors()->first($field) ?: null; } } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php deleted file mode 100644 index fdff99fc683..00000000000 --- a/app/Console/Kernel.php +++ /dev/null @@ -1,48 +0,0 @@ -command('queue:prune-batches')->daily(); - - if (config('backups.prune_age')) { - // Every 30 minutes, run the backup pruning command so that any abandoned backups can be deleted. - $schedule->command(PruneOrphanedBackupsCommand::class)->everyThirtyMinutes(); - } - - if (config('activity.prune_days')) { - $schedule->command(PruneCommand::class, ['--model' => [ActivityLog::class]])->daily(); - } - - $schedule->command(ResetUsagesCommand::class)->daily(); - $schedule->command(PruneUsersCommand::class)->daily(); - $schedule->command(UpdateUsagesCommand::class)->everyFiveMinutes(); - $schedule->command(UpdateRateLimitsCommand::class)->everyTenMinutes(); - } - - /** - * Register the commands for the application. - */ - protected function commands(): void - { - $this->load(__DIR__.'/Commands'); - - //require base_path('routes/console.php'); - } -} diff --git a/app/Contracts/Repository/ActivityRepositoryInterface.php b/app/Contracts/Repository/ActivityRepositoryInterface.php deleted file mode 100644 index 8141abfba2b..00000000000 --- a/app/Contracts/Repository/ActivityRepositoryInterface.php +++ /dev/null @@ -1,14 +0,0 @@ - */ + public array $series, + ) {} +} diff --git a/app/Data/Admin/Overview/NodeDatastoreUsageData.php b/app/Data/Admin/Overview/NodeDatastoreUsageData.php new file mode 100644 index 00000000000..ae51224f1b7 --- /dev/null +++ b/app/Data/Admin/Overview/NodeDatastoreUsageData.php @@ -0,0 +1,23 @@ + + */ + public DataCollection $datastores, + ) {} +} diff --git a/app/Data/Admin/Overview/NodeSummaryData.php b/app/Data/Admin/Overview/NodeSummaryData.php new file mode 100644 index 00000000000..0d09e7786ac --- /dev/null +++ b/app/Data/Admin/Overview/NodeSummaryData.php @@ -0,0 +1,21 @@ + $nodes */ + public DataCollection $nodes, + /** Week-over-week deltas + sparkline series for the KPI tiles (from VictoriaMetrics). */ + public OverviewTrendsData $trends, + ) {} +} diff --git a/app/Data/Admin/Overview/OverviewTrendsData.php b/app/Data/Admin/Overview/OverviewTrendsData.php new file mode 100644 index 00000000000..e244f01ee05 --- /dev/null +++ b/app/Data/Admin/Overview/OverviewTrendsData.php @@ -0,0 +1,16 @@ + $lifecycles Raw per-lifecycle counts (lifecycle value => count), + * so the UI can render buckets we don't call out explicitly. + */ + public function __construct( + public int $total, + public int $ready, + public int $installing, + public int $restoring, + public int $deleting, + public int $failed, + public int $suspended, + /** + * Servers whose placement the reconciler flagged for a human (see + * ServerPlacementService). Like `$suspended`, an independent axis -- + * not a lifecycle slice. + */ + public int $flagged, + public array $lifecycles, + ) {} +} diff --git a/app/Data/Admin/Settings/AccountSettingsData.php b/app/Data/Admin/Settings/AccountSettingsData.php new file mode 100644 index 00000000000..56a071898c8 --- /dev/null +++ b/app/Data/Admin/Settings/AccountSettingsData.php @@ -0,0 +1,24 @@ +id, + uuid: $key->uuid, + name: $key->name, + mode: $key->mode, + maxUses: $key->max_uses, + uses: $key->uses, + status: $key->status(), + expiresAt: $key->expires_at?->toIso8601String(), + revokedAt: $key->revoked_at?->toIso8601String(), + lastUsedAt: $key->last_used_at?->toIso8601String(), + token: $token ?? Optional::create(), + command: $token === null + ? Optional::create() + : sprintf( + "anchor enroll --panel-url %s --token '%s'", + // No installation exists yet to carry an override, so the + // command can only name the panel-wide address. + app(AnchorSettings::class)->resolvedPanelUrl(), + $token, + ), + createdBy: Lazy::whenLoaded( + 'createdBy', + $key, + fn () => $key->createdBy ? UserData::from($key->createdBy) : null, + ), + ); + } +} diff --git a/app/Data/Anchor/AnchorEnrollmentQueueData.php b/app/Data/Anchor/AnchorEnrollmentQueueData.php new file mode 100644 index 00000000000..372a8b2829d --- /dev/null +++ b/app/Data/Anchor/AnchorEnrollmentQueueData.php @@ -0,0 +1,68 @@ +|null $reportedFacts + * @param array $suggestions + * @param array $capabilities + */ + public function __construct( + public int $id, + public string $uuid, + public string $name, + public AnchorMode $mode, + public ?string $enrollmentKeyName, + public ?string $enrolledAt, + public ?string $lastSeenAt, + public ?string $version, + public ?int $protocolMin, + public ?int $protocolMax, + public int $panelProtocolVersion, + public array $capabilities, + public AnchorCompatibility $compatibility, + public ?array $reportedFacts, + /** + * Everything the machine already answered, shaped as node fields. The + * approval screen is a confirmation of what was found, not a blank form. + */ + public array $suggestions, + ) {} + + /** @param array $suggestions */ + public static function fromModel(AnchorEnrollment $enrollment, array $suggestions = []): self + { + return new self( + id: $enrollment->id, + uuid: $enrollment->uuid, + name: $enrollment->name, + mode: $enrollment->mode, + enrollmentKeyName: $enrollment->enrollmentKey?->name, + enrolledAt: $enrollment->enrolled_at?->toIso8601String(), + lastSeenAt: $enrollment->last_seen_at?->toIso8601String(), + version: $enrollment->version, + protocolMin: $enrollment->protocol_min, + protocolMax: $enrollment->protocol_max, + panelProtocolVersion: AnchorProtocol::VERSION, + capabilities: $enrollment->capabilities ?? [], + compatibility: $enrollment->anchorCompatibility(), + reportedFacts: $enrollment->reported_facts, + suggestions: $suggestions, + ); + } +} diff --git a/app/Data/Anchor/RelayData.php b/app/Data/Anchor/RelayData.php new file mode 100644 index 00000000000..cef30ab3c9e --- /dev/null +++ b/app/Data/Anchor/RelayData.php @@ -0,0 +1,57 @@ + $capabilities */ + public function __construct( + public int $id, + public string $uuid, + public string $name, + public ?string $publicUrl, + public ?string $panelUrlOverride, + /** The override cascade already resolved -- what the relay is actually told to call. */ + public string $panelUrl, + public int $nodesCount, + public ?string $enrollmentExpiresAt, + public ?string $enrolledAt, + public ?string $lastSeenAt, + public ?string $version, + public ?int $protocolMin, + public ?int $protocolMax, + public int $panelProtocolVersion, + public array $capabilities, + public AnchorCompatibility $compatibility, + ) {} + + public static function fromModel(Relay $relay): self + { + return new self( + id: $relay->id, + uuid: $relay->uuid, + name: $relay->name, + publicUrl: $relay->public_url, + panelUrlOverride: $relay->panel_url_override, + panelUrl: $relay->anchorPanelUrl(), + nodesCount: (int) ($relay->nodes_count ?? 0), + enrollmentExpiresAt: $relay->enrollment_expires_at?->toIso8601String(), + enrolledAt: $relay->enrolled_at?->toIso8601String(), + lastSeenAt: $relay->last_seen_at?->toIso8601String(), + version: $relay->version, + protocolMin: $relay->protocol_min, + protocolMax: $relay->protocol_max, + panelProtocolVersion: AnchorProtocol::VERSION, + capabilities: $relay->capabilities ?? [], + compatibility: $relay->anchorCompatibility(), + ); + } +} diff --git a/app/Data/Audit/AuditActorData.php b/app/Data/Audit/AuditActorData.php new file mode 100644 index 00000000000..7c993b52efa --- /dev/null +++ b/app/Data/Audit/AuditActorData.php @@ -0,0 +1,55 @@ +actor_type === null) { + return new self(AuditActorType::UNKNOWN, 'Unknown', null); + } + + if ($log->actor instanceof SystemActor || $log->actor_type === SystemActor::class) { + return new self(AuditActorType::SYSTEM, 'System', $log->actor_id); + } + + $label = $log->actor_label ?? 'Unknown'; + $actor = $log->actor; + + // Masking applies only to *other people's* admin actions seen by a non-admin. Viewers + // always see their own name, and admins always see the truth. + $isOtherAdmin = $actor instanceof User + && $actor->root_admin + && ! $actor->is($viewer); + + if ($isOtherAdmin && ! $viewerIsAdmin && ! app(AuditSettings::class)->reveal_staff_identity) { + return new self(AuditActorType::STAFF, 'Staff', null); + } + + return new self(AuditActorType::USER, $label, $log->actor_id); + } +} diff --git a/app/Data/Audit/AuditLogData.php b/app/Data/Audit/AuditLogData.php new file mode 100644 index 00000000000..3e00ac10bb1 --- /dev/null +++ b/app/Data/Audit/AuditLogData.php @@ -0,0 +1,59 @@ + */ + public array $properties, + public ?string $ip, + public ?string $userAgent, + public CarbonImmutable $createdAt, + ) {} + + public static function fromModel(AuditLog $model, ?Request $request = null): self + { + $request ??= request(); + + /** @var User|null $viewer */ + $viewer = $request->user() instanceof User ? $request->user() : null; + $viewerIsAdmin = (bool) $viewer?->root_admin; + + // An address is personal data about whoever acted. Admins investigating need it; everyone + // else only ever sees their own. + $canSeeAddress = $viewerIsAdmin + || ($viewer !== null && $model->actor instanceof User && $model->actor->is($viewer)); + + return new self( + id: $model->id, + event: $model->event, + batch: $model->batch, + actor: AuditActorData::forViewer($model, $viewer, $viewerIsAdmin), + subject: AuditSubjectData::fromModel($model), + properties: $model->properties->toArray(), + ip: $canSeeAddress ? $model->ip : null, + userAgent: $canSeeAddress ? $model->user_agent : null, + createdAt: CarbonImmutable::parse($model->created_at), + ); + } +} diff --git a/app/Data/Audit/AuditSubjectData.php b/app/Data/Audit/AuditSubjectData.php new file mode 100644 index 00000000000..799ba80c718 --- /dev/null +++ b/app/Data/Audit/AuditSubjectData.php @@ -0,0 +1,42 @@ +subject_type === null) { + return null; + } + + $subject = $log->subject; + + return new self( + type: Str::lower(class_basename($log->subject_type)), + id: $log->subject_id, + label: $subject?->getAttribute('name') + ?? $subject?->getAttribute('short_code') + ?? $subject?->getAttribute('display_name'), + ); + } +} diff --git a/app/Data/Auth/SSOTokenData.php b/app/Data/Auth/SSOTokenData.php new file mode 100644 index 00000000000..58dcc3cbf13 --- /dev/null +++ b/app/Data/Auth/SSOTokenData.php @@ -0,0 +1,17 @@ + $nodes + * @param Collection $servers + * @param Collection $storages + */ + public function __construct( + public Collection $nodes, + public Collection $servers, + public Collection $storages, + ) {} +} diff --git a/app/Data/Cluster/ClusterStatusData.php b/app/Data/Cluster/ClusterStatusData.php new file mode 100644 index 00000000000..ab8308b49b6 --- /dev/null +++ b/app/Data/Cluster/ClusterStatusData.php @@ -0,0 +1,19 @@ + $memberNames + */ + public function __construct( + public ?string $clusterName, + public array $memberNames, + ) {} +} diff --git a/app/Data/Cluster/NodeResourceData.php b/app/Data/Cluster/NodeResourceData.php new file mode 100644 index 00000000000..7854279013e --- /dev/null +++ b/app/Data/Cluster/NodeResourceData.php @@ -0,0 +1,38 @@ +type); + } + + public static function fromRaw(array $raw): self + { + return new self( + name: Arr::get($raw, 'storage', ''), + nodeName: Arr::get($raw, 'node', ''), + // `disk`/`maxdisk` mean used/total bytes for storage rows, where for + // a guest row they would mean its root image. Same keys, different + // question -- which is why these are only read off `type=storage`. + used: (int) Arr::get($raw, 'disk', 0), + total: (int) Arr::get($raw, 'maxdisk', 0), + status: (string) Arr::get($raw, 'status', 'unknown'), + shared: (bool) Arr::get($raw, 'shared', false), + type: Arr::get($raw, 'plugintype'), + content: Arr::get($raw, 'content'), + ); + } +} diff --git a/app/Data/Helpers/ChecksumData.php b/app/Data/Helpers/ChecksumData.php index 54c7a61466a..eff9b4a4de3 100644 --- a/app/Data/Helpers/ChecksumData.php +++ b/app/Data/Helpers/ChecksumData.php @@ -1,16 +1,14 @@ */ + public Lazy|DataCollection $versions, + ) {} + + public static function fromModel(ImageDefinition $definition): self + { + $latest = $definition->relationLoaded('versions') + ? $definition->versions->where('is_active', true)->sortByDesc( + fn ($v) => [$v->version_major, $v->version_minor, $v->version_patch], + )->first() + : $definition->latestVersion(); + + return new self( + uuid: $definition->uuid, + imageGroupUuid: $definition->group->uuid, + name: $definition->name, + description: $definition->description, + isAdminOnly: (bool) $definition->is_admin_only, + ostype: $definition->ostype, + hardware: $definition->hardware ?? [], + effectiveHardware: $definition->effectiveHardware(), + minimumCores: $definition->minimum_cores, + minimumMemory: $definition->minimum_memory, + latestVersion: $latest ? ImageVersionData::fromModel($latest) : null, + versions: Lazy::whenLoaded( + 'versions', + $definition, + fn () => ImageVersionData::collect($definition->versions, DataCollection::class), + ), + ); + } +} diff --git a/app/Data/Image/ImageDiskData.php b/app/Data/Image/ImageDiskData.php new file mode 100644 index 00000000000..abdbc135dfa --- /dev/null +++ b/app/Data/Image/ImageDiskData.php @@ -0,0 +1,59 @@ +role === ImageDiskRole::SYSTEM; + } + + public function isHosted(): bool + { + return filled($this->path); + } +} diff --git a/app/Data/Image/ImageGroupData.php b/app/Data/Image/ImageGroupData.php new file mode 100644 index 00000000000..7ea67bfacdf --- /dev/null +++ b/app/Data/Image/ImageGroupData.php @@ -0,0 +1,42 @@ + */ + public Lazy|DataCollection $definitions, + ) {} + + public static function fromModel(ImageGroup $group): self + { + return new self( + uuid: $group->uuid, + name: $group->name, + description: $group->description, + icon: $group->icon, + isAdminOnly: (bool) $group->is_admin_only, + definitions: Lazy::whenLoaded( + 'definitions', + $group, + fn () => ImageDefinitionData::collect($group->definitions, DataCollection::class), + ), + ); + } +} diff --git a/app/Data/Image/ImageVersionData.php b/app/Data/Image/ImageVersionData.php new file mode 100644 index 00000000000..63eb854e32f --- /dev/null +++ b/app/Data/Image/ImageVersionData.php @@ -0,0 +1,37 @@ + */ + public DataCollection $disks, + /** Total bytes a node has to transfer for this version. */ + public int $size, + /** The provisioned size of the system disk: the smallest plan that fits. */ + public int $minimumDisk, + public bool $isActive, + ) {} + + public static function fromModel(ImageVersion $version): self + { + return new self( + uuid: $version->uuid, + version: $version->version, + disks: ImageDiskData::collect($version->diskSet()->all(), DataCollection::class), + size: (int) $version->size, + minimumDisk: $version->minimumDiskSize(), + isActive: (bool) $version->is_active, + ); + } +} diff --git a/app/Data/Ipam/AddressBlockData.php b/app/Data/Ipam/AddressBlockData.php new file mode 100644 index 00000000000..7aa91bce60b --- /dev/null +++ b/app/Data/Ipam/AddressBlockData.php @@ -0,0 +1,44 @@ +id, + addressBlockGroupId: $block->address_block_group_id, + name: $block->name, + description: $block->description, + version: $block->version, + baseIp: $block->base_ip, + gateway: $block->gateway, + macAddress: $block->mac_address, + prefixLengthFrom: $block->prefix_length_from, + prefixLengthTo: $block->prefix_length_to, + capacity: AddressCapacityData::forBlock($block), + ); + } +} diff --git a/app/Data/Ipam/AddressBlockGroupData.php b/app/Data/Ipam/AddressBlockGroupData.php new file mode 100644 index 00000000000..08c6ae6d717 --- /dev/null +++ b/app/Data/Ipam/AddressBlockGroupData.php @@ -0,0 +1,33 @@ +id, + name: $group->name, + description: $group->description, + addressBlocksCount: (int) ($group->address_blocks_count ?? 0), + nodesCount: (int) ($group->nodes_count ?? 0), + capacity: AddressCapacityData::forGroup($group), + ); + } +} diff --git a/app/Data/Ipam/AddressCapacityData.php b/app/Data/Ipam/AddressCapacityData.php new file mode 100644 index 00000000000..797cabbf417 --- /dev/null +++ b/app/Data/Ipam/AddressCapacityData.php @@ -0,0 +1,91 @@ +totalUnits(), + isSparse: $block->isSparse(), + generatedCount: (int) ($block->addresses_count ?? 0), + assignedCount: (int) ($block->assigned_addresses_count ?? 0), + reservedCount: (int) ($block->reserved_addresses_count ?? 0), + systemCount: (int) ($block->system_addresses_count ?? 0), + availableCount: (int) ($block->available_addresses_count ?? 0), + ); + } + + /** + * A pool's capacity is the sum of its sized blocks'. + * + * A sparse block is not folded in and not allowed to erase the answer: collapsing the whole + * pool to "unknown" because one v6 block sits beside a /24 hides that the /24 is nearly full, + * which is the thing the operator opened the screen for. The sparse blocks are counted and + * named separately, and the counts above are already scoped to the dense ones. + */ + public static function forGroup(AddressBlockGroup $group): self + { + $blocks = $group->relationLoaded('addressBlocks') + ? $group->addressBlocks + : $group->addressBlocks()->get(); + + $dense = $blocks->reject(fn (AddressBlock $block) => $block->isSparse()); + $sparseCount = $blocks->count() - $dense->count(); + + return new self( + // Null only when there is no sized block at all — then there really is no denominator. + totalUnits: $dense->isEmpty() + ? null + : (int) $dense->sum(fn (AddressBlock $block) => $block->totalUnits() ?? 0), + isSparse: $dense->isEmpty() && $sparseCount > 0, + generatedCount: (int) ($group->addresses_count ?? 0), + assignedCount: (int) ($group->assigned_addresses_count ?? 0), + reservedCount: (int) ($group->reserved_addresses_count ?? 0), + systemCount: (int) ($group->system_addresses_count ?? 0), + availableCount: (int) ($group->available_addresses_count ?? 0), + sparseBlockCount: $sparseCount, + ); + } +} diff --git a/app/Data/Ipam/AddressMapData.php b/app/Data/Ipam/AddressMapData.php new file mode 100644 index 00000000000..85f92b80711 --- /dev/null +++ b/app/Data/Ipam/AddressMapData.php @@ -0,0 +1,36 @@ + */ + public array $units, + ) {} +} diff --git a/app/Data/Ipam/AddressMapUnitData.php b/app/Data/Ipam/AddressMapUnitData.php new file mode 100644 index 00000000000..36eec2639ac --- /dev/null +++ b/app/Data/Ipam/AddressMapUnitData.php @@ -0,0 +1,23 @@ +id, + addressBlockId: $address->address_block_id, + serverId: $address->server_id, + state: $address->state, + stateReason: $address->state_reason, + version: $address->version, + ip: $address->ip, + prefixLength: $address->prefix_length, + gateway: $address->gateway, + macAddress: $address->mac_address, + server: Lazy::whenLoaded( + 'server', + $address, + fn () => $address->server + ? ServerData::from($address->server) + : null, + ), + addressBlock: Lazy::whenLoaded( + 'addressBlock', + $address, + fn () => AddressBlockData::from($address->addressBlock), + ), + ); + } +} diff --git a/app/Data/Ipam/IpamSummaryData.php b/app/Data/Ipam/IpamSummaryData.php new file mode 100644 index 00000000000..da32e45acda --- /dev/null +++ b/app/Data/Ipam/IpamSummaryData.php @@ -0,0 +1,28 @@ +id, + shortCode: $location->short_code, + description: $location->description, + nodesCount: (int) ($location->nodes_count ?? 0), + serversCount: (int) ($location->servers_count ?? 0), + ); + } +} diff --git a/app/Data/Node/Access/CreateUserData.php b/app/Data/Node/Access/CreateUserData.php index 48313e88c3e..40c4fff029c 100644 --- a/app/Data/Node/Access/CreateUserData.php +++ b/app/Data/Node/Access/CreateUserData.php @@ -1,27 +1,25 @@ explode('@', $raw['username'])[0], - 'realm_type' => RealmType::from(explode('@', $raw['username'])[1]), + 'realmType' => RealmType::from(explode('@', $raw['username'])[1]), 'ticket' => $raw['ticket'], - 'csrf_token' => $raw['CSRFPreventionToken'], + 'csrfToken' => $raw['CSRFPreventionToken'], ]); } -} \ No newline at end of file +} diff --git a/app/Data/Node/Access/UserData.php b/app/Data/Node/Access/UserData.php index bc30b20a550..b9ac69be32b 100644 --- a/app/Data/Node/Access/UserData.php +++ b/app/Data/Node/Access/UserData.php @@ -1,35 +1,33 @@ explode('@', $raw['userid'])[0], 'email' => Arr::get($raw, 'email'), - 'realm_type' => RealmType::from($raw['realm-type']), - 'enabled' => (bool)$raw['enable'], - 'expires_at' => Arr::get($raw, 'expire') ? Carbon::createFromTimestamp($raw['expire']) : null, + 'realmType' => RealmType::from($raw['realm-type']), + 'enabled' => (bool) $raw['enable'], + 'expiresAt' => Arr::get($raw, 'expire') ? Carbon::createFromTimestamp($raw['expire']) : null, ]); } } diff --git a/app/Data/Node/NetworkInterfaceData.php b/app/Data/Node/NetworkInterfaceData.php new file mode 100644 index 00000000000..b23e0acbbce --- /dev/null +++ b/app/Data/Node/NetworkInterfaceData.php @@ -0,0 +1,104 @@ + + */ + public DataCollection $vlans, + #[LoadRelation] + public Lazy|NodeData $node, + ) {} + + public static function fromModel(NetworkInterface $interface): self + { + return new self( + id: $interface->id, + nodeId: $interface->node_id, + name: $interface->name, + description: $interface->description, + isVlanAware: $interface->is_vlan_aware, + vlanTag: $interface->vlan_tag, + serversCount: (int) ($interface->servers_count ?? 0), + addressPoolsCount: (int) ($interface->address_block_groups_count ?? 0), + // Explicitly unwrapped: returned inside a collection the nested + // VLANs serialize as a bare array, but returned as a single + // resource they would pick up the global `data` wrap and arrive as + // `vlans.data`. The client merges write responses into the list it + // got from index, so the two shapes have to agree. + vlans: VlanData::collect(self::vlansFor($interface), DataCollection::class) + ->withoutWrapping(), + node: Lazy::whenLoaded( + 'node', + $interface, + fn () => NodeData::from($interface->node), + ), + ); + } + + /** + * Declared VLANs merged with the tags actually in use, tag-ascending. + * + * The two sets overlap but neither contains the other: a trunk can be + * configured with VLANs nothing sits on yet, and a server can carry a tag + * that was never declared. Dropping either would make the tree lie. + * + * @return VlanData[] + */ + private static function vlansFor(NetworkInterface $interface): array + { + if (! $interface->is_vlan_aware) { + return []; + } + + $usage = $interface->vlanUsage(); + $declared = $interface->relationLoaded('vlans') + ? $interface->vlans + : $interface->vlans()->get(); + + return $declared + ->map(function (Vlan $vlan) use ($usage) { + $vlan->servers_count = (int) $usage->get($vlan->tag, 0); + + return VlanData::from($vlan); + }) + ->concat( + $usage->keys() + ->diff($declared->pluck('tag')) + ->map(fn (int $tag) => VlanData::undeclared( + $interface->id, + $tag, + $usage->get($tag), + )), + ) + ->sortBy('tag') + ->values() + ->all(); + } +} diff --git a/app/Data/Node/NodeData.php b/app/Data/Node/NodeData.php new file mode 100644 index 00000000000..b5c8448d0d3 --- /dev/null +++ b/app/Data/Node/NodeData.php @@ -0,0 +1,130 @@ + */ + public array $agentCapabilities, + public int $serversCount, + /** + * Reachability as of {@see $statusCheckedAt}, written by `nodes:poll` + * and degraded to `unknown` once too stale to trust. Never read live + * per request: see docs/node-status-plan.md. + */ + public NodeStatus $status = NodeStatus::UNKNOWN, + /** Why it is unreachable, in the connection test's vocabulary. */ + public ?ConnectionErrorCode $statusCode = null, + /** Last *successful* contact, so the UI can say how stale this is. */ + public ?string $lastSeenAt = null, + public ?string $statusCheckedAt = null, + /** + * This node's override of the quota-overage penalty. Null = inherit the + * global tier, which is what {@see $defaultOveragePenalty} carries. + */ + public ?OveragePenaltyData $overagePenalty = null, + /** + * The global-tier default this node falls back to when it has no + * override. Sent so the settings UI can show the resolved *effective* + * value while the field is left on "Inherit"; it is read-only here and + * is edited on the global Settings screen. + */ + public ?OveragePenaltyData $defaultOveragePenalty = null, + ) {} + + public static function fromModel(Node $node): self + { + return new self( + id: $node->id, + locationId: $node->location_id, + displayName: $node->display_name, + name: $node->name, + clusterName: $node->cluster?->name, + clusterId: $node->cluster_id, + clusterFlaggedAt: $node->cluster?->flagged_at?->toIso8601String(), + clusterFlagReason: $node->cluster?->flag_reason, + verifyTls: $node->verify_tls, + fqdn: $node->fqdn, + port: $node->port, + socketCount: $node->socket_count, + coreCount: $node->core_count, + cpuCount: $node->cpu_count, + memory: (int) $node->memory, + memoryOverallocate: $node->memory_overallocate, + memoryAllocated: (int) ($node->memory_allocated ?? 0), + relayId: $node->relay_id, + agentCompatibility: $node->hasAnchor() ? $node->anchorCompatibility() : null, + agentVersion: $node->agent_version, + agentPublicUrl: $node->agent_public_url, + agentLastSeenAt: $node->agent_last_seen_at?->toIso8601String(), + agentCapabilities: $node->agent_capabilities ?? [], + serversCount: (int) ($node->servers_count ?? 0), + status: $node->currentStatus(), + // Only meaningful alongside a live `unreachable`; a stale row keeps + // its last code in the database, but sending it with an `unknown` + // status would invite the UI to explain a failure it cannot vouch for. + statusCode: $node->currentStatus() === NodeStatus::UNREACHABLE + ? $node->status_code + : null, + lastSeenAt: $node->last_seen_at?->toIso8601String(), + statusCheckedAt: $node->status_checked_at?->toIso8601String(), + overagePenalty: $node->overage_penalty, + defaultOveragePenalty: app(OveragePenaltyResolver::class)->global(), + ); + } +} diff --git a/app/Data/Node/Status/BootInfoData.php b/app/Data/Node/Status/BootInfoData.php new file mode 100644 index 00000000000..348cd9d785b --- /dev/null +++ b/app/Data/Node/Status/BootInfoData.php @@ -0,0 +1,14 @@ +uuid, + name: $iso->name, + fileName: $iso->file_name, + url: $iso->url, + isHosted: $iso->isHosted(), + sha256: $iso->sha256, + size: $iso->getRawOriginal('size') !== null ? (int) $iso->size : null, + hidden: (bool) $iso->hidden, + createdAt: CarbonImmutable::parse($iso->created_at), + ); + } +} diff --git a/app/Data/Node/Storage/IsoData.php b/app/Data/Node/Storage/IsoData.php deleted file mode 100644 index 79484df4bf0..00000000000 --- a/app/Data/Node/Storage/IsoData.php +++ /dev/null @@ -1,17 +0,0 @@ -id, + networkInterfaceId: $vlan->network_interface_id, + tag: $vlan->tag, + name: $vlan->name, + description: $vlan->description, + serversCount: (int) ($vlan->servers_count ?? 0), + ); + } + + public static function undeclared(int $networkInterfaceId, int $tag, int $serversCount): self + { + return new self( + id: null, + networkInterfaceId: $networkInterfaceId, + tag: $tag, + name: null, + description: null, + serversCount: $serversCount, + ); + } +} diff --git a/app/Data/PaginationMeta.php b/app/Data/PaginationMeta.php new file mode 100644 index 00000000000..6b996b8c5b4 --- /dev/null +++ b/app/Data/PaginationMeta.php @@ -0,0 +1,43 @@ +total(), + count: count($paginator->items()), + perPage: $paginator->perPage(), + currentPage: $paginator->currentPage(), + totalPages: $paginator->lastPage(), + ); + } + + /** + * Wrap a paginator into the camelCase wire envelope. + * + * @param class-string $dataClass + * @return array{items: DataCollection, pagination: self} + */ + public static function paginate(LengthAwarePaginator $paginator, string $dataClass): array + { + return [ + 'items' => $dataClass::collect($paginator->items(), DataCollection::class), + 'pagination' => self::fromPaginator($paginator), + ]; + } +} diff --git a/app/Data/Server/Backup/BackupEloquentData.php b/app/Data/Server/Backup/BackupEloquentData.php new file mode 100644 index 00000000000..b5b49280f30 --- /dev/null +++ b/app/Data/Server/Backup/BackupEloquentData.php @@ -0,0 +1,54 @@ +id, + uuid: $backup->uuid, + serverId: $backup->server_id, + storageId: $backup->storage_id, + name: $backup->name, + description: $backup->description, + isLocked: (bool) $backup->is_locked, + // The code is a safe, friendly enum shown to the backup owner; the + // raw Proxmox message can leak node internals, so it is admin-only. + errorCode: $backup->error_code, + errorMessage: Auth::user()?->root_admin ? $backup->error_message : null, + fileName: $backup->file_name, + size: $backup->getRawOriginal('size') !== null ? (int) $backup->size : null, + completedAt: $backup->completed_at + ? CarbonImmutable::parse($backup->completed_at) + : null, + createdAt: CarbonImmutable::parse($backup->created_at), + ); + } +} diff --git a/app/Data/Server/ConsoleCredentialsData.php b/app/Data/Server/ConsoleCredentialsData.php new file mode 100644 index 00000000000..8bcefe3c18e --- /dev/null +++ b/app/Data/Server/ConsoleCredentialsData.php @@ -0,0 +1,16 @@ + */ + public Lazy|DataCollection $steps, + ) {} + + public static function fromModel(Deployment $deployment): self + { + return new self( + id: $deployment->id, + serverId: $deployment->server_id, + imageDefinitionId: $deployment->image_definition_id, + imageVersionId: $deployment->image_version_id, + status: $deployment->status, + type: $deployment->type, + startOnCompletion: (bool) $deployment->start_on_completion, + requestedAt: CarbonImmutable::parse($deployment->requested_at), + completedAt: $deployment->completed_at + ? CarbonImmutable::parse($deployment->completed_at) + : null, + image: Lazy::whenLoaded( + 'imageDefinition', + $deployment, + fn () => $deployment->imageDefinition + ? ImageDefinitionData::from($deployment->imageDefinition) + : null, + ), + steps: Lazy::whenLoaded( + 'steps', + $deployment, + fn () => DeploymentStepData::collect( + $deployment->steps, + DataCollection::class, + ), + ), + ); + } +} diff --git a/app/Data/Server/Deployments/DeploymentStepData.php b/app/Data/Server/Deployments/DeploymentStepData.php new file mode 100644 index 00000000000..b357b49be90 --- /dev/null +++ b/app/Data/Server/Deployments/DeploymentStepData.php @@ -0,0 +1,53 @@ +root_admin; + + return new self( + id: $step->id, + name: $step->name, + status: $step->status, + progressMode: $step->progress_mode, + sequence: $step->sequence, + progressCurrent: $step->progress_current, + progressTotal: $step->progress_total, + startedAt: $step->started_at + ? CarbonImmutable::parse($step->started_at) + : null, + completedAt: $step->completed_at + ? CarbonImmutable::parse($step->completed_at) + : null, + errorCode: $isAdmin ? $step->error_code : null, + errorMessage: $isAdmin ? $step->error_message : null, + ); + } +} diff --git a/app/Data/Server/Deployments/ServerDeploymentData.php b/app/Data/Server/Deployments/ServerDeploymentData.php index 2026f5823b1..e203d8830e6 100644 --- a/app/Data/Server/Deployments/ServerDeploymentData.php +++ b/app/Data/Server/Deployments/ServerDeploymentData.php @@ -1,20 +1,14 @@ action === OveragePenaltyAction::THROTTLE; + } + + public function isDisconnect(): bool + { + return $this->action === OveragePenaltyAction::DISCONNECT; + } +} diff --git a/app/Data/Server/Power/PendingPowerActionData.php b/app/Data/Server/Power/PendingPowerActionData.php new file mode 100644 index 00000000000..36571d2581b --- /dev/null +++ b/app/Data/Server/Power/PendingPowerActionData.php @@ -0,0 +1,19 @@ + Arr::get($raw, $key, $default); + + $exitStatus = $get('exitstatus'); + + return new self( + uniqueProcessId: $get('upid'), + node: $get('node'), + processId: (int) $get('pid'), + processStartTime: (int) $get('pstart'), + startTime: CarbonImmutable::createFromTimestamp($get('starttime')), + endTime: $get('endtime') ? CarbonImmutable::createFromTimestamp($get('endtime')) : null, + type: $get('type'), + targetId: $get('id'), + user: $get('user'), + // A running task reports neither field yet; guard the nulls rather + // than pass them to tryFrom(), which only accepts string|int. + status: $get('status') !== null ? TaskStatus::tryFrom($get('status')) : null, + exitStatus: $exitStatus !== null ? (TaskExitStatus::tryFrom($exitStatus) ?? $exitStatus) : null, + ); + } +} diff --git a/app/Data/Server/Proxmox/Activity/TaskLogData.php b/app/Data/Server/Proxmox/Activity/TaskLogData.php new file mode 100644 index 00000000000..b5d62020a5f --- /dev/null +++ b/app/Data/Server/Proxmox/Activity/TaskLogData.php @@ -0,0 +1,22 @@ + $ipConfigs + * + * Per-NIC cloud-init IP config, keyed by NIC index (`ipconfig{n}`). + */ + public Collection $ipConfigs, + ) {} + + public static function fromRaw(array $raw): self + { + $get = fn (string $key, $default = null) => Arr::get($raw, $key, $default); + $exists = fn (string $key) => Arr::exists($raw, $key); + + return new self( + type: $exists('citype') ? CloudinitType::from($get('citype')) : null, + username: $get('ciuser'), + password: $get('cipassword'), + custom: $get('cicustom'), + isAutoUpgradeEnabled: $get('ciupgrade', false), + searchDomain: $get('searchdomain'), + sshKeys: $exists('sshkeys') ? rawurldecode($get('sshkeys')) : null, + ipConfigs: collect($raw) + ->filter(fn ($value, $key) => preg_match('/^ipconfig\d+$/', $key)) + ->mapWithKeys(fn ($value, $key) => [ + (int) substr($key, strlen('ipconfig')) => IpConfigData::fromString($value), + ]), + ); + } +} diff --git a/app/Data/Server/Proxmox/Config/CpuConfigData.php b/app/Data/Server/Proxmox/Config/CpuConfigData.php new file mode 100644 index 00000000000..208aa637ca8 --- /dev/null +++ b/app/Data/Server/Proxmox/Config/CpuConfigData.php @@ -0,0 +1,76 @@ + Arr::get($raw, $key, $default); + + return new self( + emulatedType: $get('cpu', 'kvm64'), + coreCount: $get('cores', 1), + socketCount: $get('sockets', 1), + usageLimit: $get('cpulimit', 0), + weight: $get('cpuunits', 100), + freezeAtStartup: $get('freeze', false), + isNumaEnabled: $get('numa', false), + hotpluggedVCpuCount: $get('vcpus', 0), + affinity: $get('affinity'), + ); + } +} diff --git a/app/Data/Server/Proxmox/Config/DiskData.php b/app/Data/Server/Proxmox/Config/DiskData.php index 8e33fb6c3a2..69e37577bed 100644 --- a/app/Data/Server/Proxmox/Config/DiskData.php +++ b/app/Data/Server/Proxmox/Config/DiskData.php @@ -1,24 +1,256 @@ interface->value; + } - public bool $is_media, - public ?string $media_name, + /** + * Get the base interface type (ide, sata, scsi, virtio, etc.) + */ + public function getBaseInterfaceType(): string + { + return $this->interface->getBaseType(); + } - public int $size, - ) + public static function fromRaw(string $key, string $rawValue): self { + [$head, $pairs] = PropertyList::explode($rawValue); + + // The head is the backing volume, sometimes written explicitly as `file=`. + $volume = str_starts_with($head, 'file=') ? substr($head, 5) : $head; + + // The interface (ide0, scsi1, ...) comes from the config key, not the value. + $interface = DiskInterface::IDE0; + if (preg_match('/^(ide|sata|scsi|virtio|efidisk|tpmstate)(\d+)$/', $key, $matches)) { + $interfaceName = strtoupper($matches[1]).(int) $matches[2]; + if (defined(DiskInterface::class.'::'.$interfaceName)) { + $interface = constant(DiskInterface::class.'::'.$interfaceName); + } + } + + // The 1/0 boolean flags and string identity fields map straight off the + // attributes. Everything below needs bespoke handling the one-key-per- + // property attribute model can't express: an unbacked enum, defensive + // tryFrom() enums, a unit-suffixed size, dual-unit (mbps|bps) bandwidth, + // and integer fields that fall back to 0 rather than null. + [$mapped] = self::mapProxmoxProperties($pairs); + + $get = fn (string $k, $default = null) => data_get($pairs, $k, $default); + + // Proxmox's raw `media` value maps onto the enum; anything but cdrom is a + // regular disk. + $diskMediaType = match ($get('media')) { + 'cdrom' => DiskMediaType::CDROM, + default => DiskMediaType::DISK, + }; + + // size carries an optional K/M/G/T unit suffix scaling it into bytes. + $size = filled($get('size')) ? (ByteUnit::parseSize($get('size')) ?? 0) : 0; + + // These enums use tryFrom() (null/RAW on an unknown value) so an + // unfamiliar PVE-version value degrades gracefully rather than throwing. + $format = filled($get('format')) ? (DiskFormat::tryFrom($get('format')) ?? DiskFormat::RAW) : DiskFormat::RAW; + $cacheMode = filled($get('cache')) ? DiskCacheMode::tryFrom($get('cache')) : null; + $aioMode = filled($get('aio')) ? DiskAioMode::tryFrom($get('aio')) : null; + $discardMode = filled($get('discard')) ? DiskDiscardMode::tryFrom($get('discard')) : null; + $readErrorAction = filled($get('rerror')) ? DiskReadErrorAction::tryFrom($get('rerror')) : null; + $writeErrorAction = filled($get('werror')) ? DiskWriteErrorAction::tryFrom($get('werror')) : null; + $translationMode = filled($get('trans')) ? DiskTranslationMode::tryFrom($get('trans')) : null; + + // Bandwidth limits accept either a byte value or an mbps value (which + // wins when both are present) that scales up to bytes. + $mbps = fn (string $key) => ByteUnit::Mebibytes->toBytes((float) $get($key)); + $bps = match (true) { + filled($get('mbps')) => $mbps('mbps'), + filled($get('bps')) => (int) $get('bps'), + default => null, + }; + $bpsRead = match (true) { + filled($get('mbps_rd')) => $mbps('mbps_rd'), + filled($get('bps_rd')) => (int) $get('bps_rd'), + default => null, + }; + $bpsWrite = match (true) { + filled($get('mbps_wr')) => $mbps('mbps_wr'), + filled($get('bps_wr')) => (int) $get('bps_wr'), + default => null, + }; + $bpsMax = filled($get('mbps_max')) ? $mbps('mbps_max') : null; + $bpsReadMax = filled($get('mbps_rd_max')) ? $mbps('mbps_rd_max') : null; + $bpsWriteMax = filled($get('mbps_wr_max')) ? $mbps('mbps_wr_max') : null; + + // Length limits accept a *_max_length key or an older *_length alias. + $bpsReadMaxLength = $get('bps_rd_max_length', $get('bps_rd_length')); + $bpsReadMaxLength = filled($bpsReadMaxLength) ? (int) $bpsReadMaxLength : null; + $bpsWriteMaxLength = $get('bps_wr_max_length', $get('bps_wr_length')); + $bpsWriteMaxLength = filled($bpsWriteMaxLength) ? (int) $bpsWriteMaxLength : null; + $iopsReadMaxLength = $get('iops_rd_max_length', $get('iops_rd_length')); + $iopsReadMaxLength = filled($iopsReadMaxLength) ? (int) $iopsReadMaxLength : null; + $iopsWriteMaxLength = $get('iops_wr_max_length', $get('iops_wr_length')); + $iopsWriteMaxLength = filled($iopsWriteMaxLength) ? (int) $iopsWriteMaxLength : null; + + return new self( + interface: $interface, + volume: $volume, + diskMediaType: $diskMediaType, + size: $size, + format: $format, + cacheMode: $cacheMode, + aioMode: $aioMode, + discardMode: $discardMode, + isEmulatingSSD: $mapped['isEmulatingSSD'] ?? false, + isIncludedInBackup: $mapped['isIncludedInBackup'] ?? true, + isReplicated: $mapped['isReplicated'] ?? true, + isReadonly: $mapped['isReadonly'] ?? false, + isIOThreadEnabled: $mapped['isIOThreadEnabled'] ?? false, + bps: $bps, + bpsMax: $bpsMax, + bpsRead: $bpsRead, + bpsReadMax: $bpsReadMax, + bpsWrite: $bpsWrite, + bpsWriteMax: $bpsWriteMax, + iops: (int) $get('iops'), + iopsMax: (int) $get('iops_max'), + iopsRead: (int) $get('iops_rd'), + iopsReadMax: (int) $get('iops_rd_max'), + iopsWrite: (int) $get('iops_wr'), + iopsWriteMax: (int) $get('iops_wr_max'), + isSnapshot: $mapped['isSnapshot'] ?? false, + isShared: $mapped['isShared'] ?? false, + detectZeroes: $mapped['detectZeroes'] ?? false, + readErrorAction: $readErrorAction, + writeErrorAction: $writeErrorAction, + translationMode: $translationMode, + wwn: $mapped['wwn'] ?? null, + bpsMaxLength: (int) $get('bps_max_length'), + bpsReadMaxLength: $bpsReadMaxLength, + bpsWriteMaxLength: $bpsWriteMaxLength, + cylinders: (int) $get('cyls'), + heads: (int) $get('heads'), + iopsMaxLength: (int) $get('iops_max_length'), + iopsReadMaxLength: $iopsReadMaxLength, + iopsWriteMaxLength: $iopsWriteMaxLength, + model: $mapped['model'] ?? null, + product: $mapped['product'] ?? null, + queues: (int) $get('queues'), + isScsiBlock: $mapped['isScsiBlock'] ?? false, + sectors: (int) $get('secs'), + serial: $mapped['serial'] ?? null, + vendor: $mapped['vendor'] ?? null, + ); } } diff --git a/app/Data/Server/Proxmox/Config/DiskSpeedLimitsData.php b/app/Data/Server/Proxmox/Config/DiskSpeedLimitsData.php new file mode 100644 index 00000000000..98784b26c32 --- /dev/null +++ b/app/Data/Server/Proxmox/Config/DiskSpeedLimitsData.php @@ -0,0 +1,31 @@ +,gw=,ip6=,gw6=`). Modelling it lets a config sync + * compare the desired vs. stored ipconfig structurally, so an unchanged NIC isn't + * rewritten (which would enqueue a redundant Proxmox "Configure" task). + */ +class IpConfigData extends Data +{ + public function __construct( + public ?string $ip, + public ?string $gateway, + public ?string $ip6, + public ?string $gateway6, + ) {} + + public static function fromString(string $raw): self + { + $pairs = []; + foreach (array_filter(explode(',', $raw)) as $part) { + if (! str_contains($part, '=')) { + continue; + } + [$key, $value] = explode('=', $part, 2); + $pairs[$key] = $value; + } + + return new self( + ip: $pairs['ip'] ?? null, + gateway: $pairs['gw'] ?? null, + ip6: $pairs['ip6'] ?? null, + gateway6: $pairs['gw6'] ?? null, + ); + } +} diff --git a/app/Data/Server/Proxmox/Config/MediaData.php b/app/Data/Server/Proxmox/Config/MediaData.php deleted file mode 100644 index 00740a063b0..00000000000 --- a/app/Data/Server/Proxmox/Config/MediaData.php +++ /dev/null @@ -1,14 +0,0 @@ - $extraProperties + * + * Sub-keys present on the Proxmox net string that we don't explicitly + * model. Preserved verbatim so re-emitting the device never drops a + * field PVE (or a future version) set that we don't understand. + */ + public array $extraProperties = [], + ) {} + + /** + * Creates a Collection of NetworkDeviceData instances from a raw Proxmox config array. + * + * @param array $raw The raw configuration array from Proxmox API (e.g., the 'data' object). + * @return Collection + */ + public static function fromRaw(array $raw): Collection + { + $networkDevices = collect(); + + foreach ($raw as $key => $value) { + if (! Str::startsWith($key, 'net') || ! is_string($value)) { + continue; + } + + // The positional head is `model[=macaddr]`; the rest is a key=value tail. + [$head, $pairs] = PropertyList::explode($value); + [$modelValue, $macAddress] = array_pad(explode('=', $head, 2), 2, null); + + // Typed tail fields come from the attributes; anything left over is + // kept verbatim so it survives a re-emit. + [$mapped, $extraProperties] = self::mapProxmoxProperties($pairs); + + $networkDevices->push(new self( + id: (int) Str::replace('net', '', $key), + model: NetworkDeviceModel::from(trim($modelValue)), + macAddress: $macAddress !== null ? trim($macAddress) : null, + bridge: $mapped['bridge'] ?? null, + vlanTag: $mapped['vlanTag'] ?? null, + isFirewallEnabled: $mapped['isFirewallEnabled'] ?? null, + rateLimit: $mapped['rateLimit'] ?? null, + packetQueueCount: $mapped['packetQueueCount'] ?? null, + mtu: $mapped['mtu'] ?? null, + isLinkDown: $mapped['isLinkDown'] ?? null, + vlanTrunks: $mapped['vlanTrunks'] ?? null, + extraProperties: $extraProperties, + )); + } + + return $networkDevices; + } + + /** + * Converts the NetworkDeviceData instance to a Proxmox-compatible string format. + * + * @return array{string, string} Returns a KV pair array with the key as the device ID and the value as the configuration string. + */ + public function toProxmoxString(): array + { + $head = $this->macAddress + ? "{$this->model->value}={$this->macAddress}" + : $this->model->value; + + // Modeled keys from the attributes, then any sub-keys we don't model. + $pairs = $this->toProxmoxProperties() + $this->extraProperties; + + return ["net{$this->id}", PropertyList::implode($head, $pairs)]; + } +} diff --git a/app/Data/Server/Proxmox/Config/ServerConfigData.php b/app/Data/Server/Proxmox/Config/ServerConfigData.php index 1313303b032..f84739a7b91 100644 --- a/app/Data/Server/Proxmox/Config/ServerConfigData.php +++ b/app/Data/Server/Proxmox/Config/ServerConfigData.php @@ -1,21 +1,392 @@ $bootOrder + * + * Specifies the order in which the VM tries to boot from different devices. + */ + public Collection $bootOrder, + + /** + * @var $cdromImage + * + * Used to mount an ISO file. An alias or shortcut for configuring a virtual CD/DVD drive (specifically, ide2). + */ + public ?string $cdromImage, + + public CloudinitConfigData $cloudinit, + + public CpuConfigData $cpu, + + public int $memory, + + /** + * @var $hookScriptVolumeId + * + * Script on the Proxmox host executed during VM lifetime steps (e.g., pre-start, post-stop). + */ + public ?string $hookScriptVolumeId, + + /** + * @var $hotplugFeatures + * + * Selectively enable hotplug features (network, disk, cpu, memory, usb, cloudinit). + */ + public ServerHotplugFeaturesData $hotplugFeatures, + + public ?HugePagesSetting $hugePagesSetting, + + public bool $keepHugePagesOnShutdown, + + public ?string $vncKeyboardLayout, + + public bool $isKvmHardwareVirtualizationEnabled, + + public ?bool $isRtcUsingLocalTime, + + public ?CarbonImmutable $rtcStartDate, + + public ?ProxmoxLock $lockStatus, + + public ?string $qemuConfig, + /** + * @var $migrationMaxDowntime + * + * Maximum tolerated downtime (seconds) for live migrations. + */ + public ?float $migrationMaxDowntime, + + /** + * @var $migrationMaxSpeed + * + * Maximum speed (B/s) for migrations. + */ + public ?int $migrationMaxSpeed, + + /** + * @var $name + * + * Set a name for the VM. Only used on the PVE web interface. + */ + public ?string $name, + /** + * @var Collection $nameservers + */ + public Collection $nameservers, + + /** + * @var Collection $networkDevices + */ + public Collection $networkDevices, + + public bool $startOnHostBoot, + + public OperatingSystemType $operatingSystemType, + + /** + * @var $isProtected + * + * If enabled, disables remove VM and remove disk operations. + */ + public bool $isProtected, + + /** + * @var $isRebootAllowed + * + * Allow reboot. If false, VM exits on reboot. + */ + public bool $isRebootAllowed, + + /** + * @var $rngDevice + * + * Configure a VirtIO-based Random Number Generator + */ + public ?string $rngDevice, + + /** + * @var $smbiosConfig + * + * Specify SMBIOS type 1 fields (system information). + */ + public string $smbiosConfig, + + public ?string $startupShutdownBehavior, + + public bool $isUsbTabletEnabled, + + public bool $isTimeDriftFixEnabled, + + public ?TpmStateDiskData $tpmStateDisk, + + /** + * @var Collection $unusedDisks + * + * Reference to unused volumes. This is used internally, and should not be modified manually. + * + * TODO: implement unused disk configuration parsing + */ + public Collection $unusedDisks, + + /** + * @var Collection $usbDevices + * + * TODO: Implement USB device configuration. + */ + public Collection $usbDevices, + + /** + * @var Collection $disks + */ + public Collection $disks, + + /** + * @var Collection $virtioFileSystems + * + * TODO: Implement VirtioFS configuration. + */ + public Collection $virtioFileSystems, + + /** + * @var Collection $parallelDevices + */ + public Collection $parallelDevices, + + /** + * The VM's serial devices, as their configured backing (`socket`, or a + * passed-through host device). Shaped like `$parallelDevices`. + * + * Empty means the terminal console has nothing to attach to: PVE's + * `termproxy` opens a serial terminal only against one of these. + * + * @var Collection $serialDevices + */ + public Collection $serialDevices, + + /** + * SHA1 digest of the config at fetch time. Echo it back on an update so + * PVE rejects the write if the config changed underneath us (optimistic + * concurrency). + */ + public ?string $digest = null, + + // NOTE: not all properties are added + ) {} + + public static function fromRaw(array $raw): self { + $get = fn (string $key, $default = null) => Arr::get($raw, $key, $default); + $exists = fn (string $key) => Arr::exists($raw, $key); + + // Process disks first since we need them for boot order + $disks = collect($raw) + ->filter(fn ($value, $key) => preg_match('/^(virtio|sata|scsi|ide)\d+$/', $key)) + ->map(fn ($value, $key) => DiskData::fromRaw($key, $value)); + + // Process boot order by matching disk identifiers with parsed disks + $bootDiskIdentifiers = []; + + // Parse boot order, which might be in 'legacy=' format or 'order=' format + if (isset($raw['boot'])) { + $bootConfig = $raw['boot']; + if (is_string($bootConfig)) { + // Handle legacy format (comma-separated list or just a single value) + if (str_contains($bootConfig, 'order=')) { + // `boot` is `[legacy=][,order=[;...]]`: + // `;` separates the devices *within* order, and `,` is what + // ends the property. Stopping the capture at `;` -- as this + // did -- kept only the first device, so a saved order of + // `ide2;sata0` read back as `ide2` alone and every device + // after the first appeared to switch itself off again. + preg_match('/order=([^,]+)/', $bootConfig, $matches); + if (isset($matches[1])) { + $bootDiskIdentifiers = explode(';', $matches[1]); + } + } elseif (str_contains($bootConfig, 'legacy=')) { + // Extract from legacy=c format (legacy boot order) + // This is not disk-based, but we could map c->ide0, d->ide1, etc if needed + // For now, we'll just leave it empty as we focus on disk identifiers + } else { + // If it's just a single value like 'order=ide0' + $bootDiskIdentifiers = [$bootConfig]; + } + } elseif (is_array($bootConfig) && isset($bootConfig['order'])) { + // Handle array format with 'order' key + $bootDiskIdentifiers = is_array($bootConfig['order']) + ? $bootConfig['order'] + : explode(';', $bootConfig['order']); + } + } + + // Map boot order identifiers to actual disk objects + $bootOrder = collect($bootDiskIdentifiers) + ->map(function ($diskId) use ($disks) { + return $disks->first(function ($disk) use ($diskId) { + return $disk->getFullIdentifier() === $diskId; + }); + }) + ->filter() // Remove any null values (disks that weren't found) + ->values(); // Reindex so this serialises as a JSON array, not an object + + return new self( + description : $get('description'), + isTemplate : $get('template', false), + tags : $get('tags'), + isAcpiEnabled : $get('acpi', true), + amdSevFeatures : $get('amd-sev'), + architecture : $get('arch'), + kvmArguments : $get('args'), + autoStartAfterCrash : $get('autostart', false), + memoryBalloonSize : $exists( + 'balloon', + ) ? ByteUnit::Mebibytes->toBytes((int) $raw['balloon']) : null, + memorySharesForAutoBallooning : $get('shares', 1000), + biosType : BiosType::from($get('bios', 'seabios')), + bootOrder : $bootOrder, + cdromImage : $get('cdrom'), + cloudinit : CloudinitConfigData::fromRaw($raw), + cpu : CpuConfigData::fromRaw($raw), + memory : ByteUnit::Mebibytes->toBytes((float) $get('memory')), + hookScriptVolumeId : $get('hookscript'), + hotplugFeatures : ServerHotplugFeaturesData::fromRaw($raw), + hugePagesSetting : HugePagesSetting::tryFrom( + $get('hugepages', ''), + ), + keepHugePagesOnShutdown : $get('keephugepages', false), + vncKeyboardLayout : $get('keyboard'), + isKvmHardwareVirtualizationEnabled: $get('kvm', true), + isRtcUsingLocalTime : $get('localtime'), + rtcStartDate : $exists('startdate') ? CarbonImmutable::parse( + $get('startdate'), + ) : null, + lockStatus : ProxmoxLock::tryFrom( + $get('lock', ''), + ), + qemuConfig : $get('machine'), + migrationMaxDowntime : $get('migrate_downtime', 0.1), + migrationMaxSpeed : ! $exists('migrate_speed') || $get('migrate_speed', 0) === 0 + ? null + : ByteUnit::Mebibytes->toBytes((float) $get('migrate_speed')), // Convert from MiB/s to B/s + name : $get('name'), + nameservers : collect($get('nameserver', [])) + ->map(fn (string $ns) => Factory::parseAddressString($ns)), + networkDevices : NetworkDeviceData::fromRaw($raw), + startOnHostBoot : $get('onboot', false), + operatingSystemType : OperatingSystemType::fromRaw($get('ostype', 'other')), + isProtected : $get('protection', false), + isRebootAllowed : $get('reboot', true), + rngDevice : $get('rng0'), + smbiosConfig : $get('smbios1'), + startupShutdownBehavior : $get('startup'), + isUsbTabletEnabled : $get('tablet', true), + isTimeDriftFixEnabled : $get('tdf', false), + tpmStateDisk : $exists('tpmstate0') ? TpmStateDiskData::fromRaw( + $get('tpmstate0'), + ) : null, + unusedDisks : collect($raw) + ->filter(fn ($value, $key) => preg_match('/^unused\d+$/', $key)) + ->values(), + usbDevices : collect($raw) + ->filter(fn ($value, $key) => preg_match('/^usb\d+$/', $key)) + ->map(fn ($value, $key) => UsbDeviceData::fromRaw($key, $value)), + disks : $disks, + virtioFileSystems : collect($raw) + ->filter(fn ($value, $key) => preg_match('/^virtiofs\d+$/', $key)) + ->values(), + parallelDevices : collect($raw) + ->filter(fn ($value, $key) => preg_match('/^parallel\d+$/', $key)) + ->values(), + // PVE numbers these `serial0`..`serial3` and never emits a bare + // `serial` key, so reading one left this permanently empty. + serialDevices : collect($raw) + ->filter(fn ($value, $key) => preg_match('/^serial\d+$/', $key)) + ->values(), + digest : $get('digest'), + ); } } diff --git a/app/Data/Server/Proxmox/Config/ServerHotplugFeaturesData.php b/app/Data/Server/Proxmox/Config/ServerHotplugFeaturesData.php new file mode 100644 index 00000000000..712a302df83 --- /dev/null +++ b/app/Data/Server/Proxmox/Config/ServerHotplugFeaturesData.php @@ -0,0 +1,55 @@ + Str::contains($raw['hotplug'], $feature); + + return new self( + isCpuEnabled: $isEnabled('cpu'), + isMemoryEnabled: $isEnabled('memory'), + isNetworkEnabled: $isEnabled('network'), + isDiskEnabled: $isEnabled('disk'), + isUsbEnabled: $isEnabled('usb'), + isCloudinitEnabled: $isEnabled('cloudinit'), + ); + } +} diff --git a/app/Data/Server/Proxmox/Config/TpmStateDiskData.php b/app/Data/Server/Proxmox/Config/TpmStateDiskData.php new file mode 100644 index 00000000000..b51aeac89d1 --- /dev/null +++ b/app/Data/Server/Proxmox/Config/TpmStateDiskData.php @@ -0,0 +1,89 @@ + $extraProperties + * + * Sub-keys present on the tpmstate string that we don't explicitly model. + * Preserved verbatim so re-emitting never drops a field PVE set. + */ + public array $extraProperties = [], + ) {} + + /** + * Creates a TpmStateDiskData instance from a raw Proxmox tpmstate0 config string. + * Example raw string: "local-lvm:vm-100-disk-2,size=4M,version=v2.0" + * Or just: "local-lvm:vm-100-disk-2" + * + * @param string $raw The raw configuration string from Proxmox API. + */ + public static function fromRaw(string $raw): self + { + [$head, $pairs] = PropertyList::explode($raw); + + // The head is always the backing volume — bare, or keyed as file=/volume=. + $volume = $head; + if (Str::contains($head, '=')) { + [$key, $value] = explode('=', $head, 2); + if (in_array(trim($key), ['file', 'volume'], true)) { + $volume = trim($value); + } + } + + [$mapped, $extraProperties] = self::mapProxmoxProperties($pairs); + + return new self( + volume: $volume, + version: $mapped['version'] ?? '', + size: $mapped['size'] ?? 0, + extraProperties: $extraProperties, + ); + } + + /** + * Converts the Data Object back to the Proxmox API string format. + */ + public function toProxmoxString(): string + { + // Emit the volume explicitly as file= for clarity, then the modeled + // keys, then any sub-keys we don't model. + $pairs = $this->toProxmoxProperties() + $this->extraProperties; + + return PropertyList::implode('file='.$this->volume, $pairs); + } +} diff --git a/app/Data/Server/Proxmox/Config/UsbDeviceData.php b/app/Data/Server/Proxmox/Config/UsbDeviceData.php new file mode 100644 index 00000000000..ba6ca4631b3 --- /dev/null +++ b/app/Data/Server/Proxmox/Config/UsbDeviceData.php @@ -0,0 +1,81 @@ + RuleDirection::Inbound, + 'OUT' => RuleDirection::Outbound, + default => null, + }; + } + + private static function match(string $pattern, string $subject): ?string + { + return preg_match($pattern, $subject, $matches) === 1 ? $matches[1] : null; + } +} diff --git a/app/Data/Server/Proxmox/Firewall/FirewallMacroData.php b/app/Data/Server/Proxmox/Firewall/FirewallMacroData.php new file mode 100644 index 00000000000..7698e26a8f2 --- /dev/null +++ b/app/Data/Server/Proxmox/Firewall/FirewallMacroData.php @@ -0,0 +1,29 @@ +value), + outboundPolicy: FirewallPolicy::from(Arr::get($raw, 'policy_out') ?: FirewallPolicy::Accept->value), + inboundLogLevel: FirewallLogLevel::from(Arr::get($raw, 'log_level_in') ?: FirewallLogLevel::NoLog->value), + outboundLogLevel: FirewallLogLevel::from(Arr::get($raw, 'log_level_out') ?: FirewallLogLevel::NoLog->value), + digest: Arr::get($raw, 'digest'), + ); + } +} diff --git a/app/Data/Server/Proxmox/Firewall/FirewallRefData.php b/app/Data/Server/Proxmox/Firewall/FirewallRefData.php new file mode 100644 index 00000000000..59cb9bb94b4 --- /dev/null +++ b/app/Data/Server/Proxmox/Firewall/FirewallRefData.php @@ -0,0 +1,43 @@ + PVE key`. + * + * Drives both directions of the mapping and, more importantly, + * {@see clearedKeysAgainst()}: Proxmox does not treat an empty string as + * "unset", so removing a comment or a port means naming the key in the + * request's `delete` list. Keeping one list means a new field can never be + * writable but un-clearable. + */ + public const OPTIONAL_KEYS = [ + 'macro' => 'macro', + 'protocol' => 'proto', + 'sourceAddress' => 'source', + 'destinationAddress' => 'dest', + 'sourcePort' => 'sport', + 'destinationPort' => 'dport', + 'icmpType' => 'icmp-type', + 'interface' => 'iface', + 'logLevel' => 'log', + 'comment' => 'comment', + ]; + + public function __construct( + /** Index in the ruleset. Null for a rule that has not been created yet. */ + public ?int $position, + + public RuleDirection $direction, + + public RuleAction $action, + + public bool $isEnabled, + + /** Predefined Proxmox macro (`SSH`, `HTTP`, ...) standing in for protocol + port. */ + public ?string $macro, + + public ?string $protocol, + + /** An address, CIDR, range, comma-list, alias name, or `+ipset` reference. */ + public ?string $sourceAddress, + + public ?string $destinationAddress, + + /** A port, a `80:85` range, or a comma-separated list of either. */ + public ?string $sourcePort, + + public ?string $destinationPort, + + public ?string $icmpType, + + /** A `net0`-style device name, restricting the rule to one interface. */ + public ?string $interface, + + public ?FirewallLogLevel $logLevel, + + public ?string $comment, + + /** + * Hash of the firewall config this rule was read from, sent back on a + * write so Proxmox refuses it if anything moved in between. + * + * This matters more here than it does for options: a rule's identity + * is its index, and indices renumber on every insert and delete. + * Without the digest, deleting "rule 2" after someone else inserted + * one above it deletes a different rule than the one the user saw. + */ + public ?string $digest, + ) {} + + public static function fromRaw(array $raw): self + { + return new self( + position: Arr::get($raw, 'pos'), + direction: RuleDirection::from(Arr::get($raw, 'type')), + action: RuleAction::from(Arr::get($raw, 'action')), + // Rule-level `enable` is an integer, unlike the boolean of the same + // name in firewall options. Absent means enabled, matching Proxmox. + isEnabled: (bool) Arr::get($raw, 'enable', 1), + macro: Arr::get($raw, 'macro'), + protocol: Arr::get($raw, 'proto'), + sourceAddress: Arr::get($raw, 'source'), + destinationAddress: Arr::get($raw, 'dest'), + sourcePort: Arr::get($raw, 'sport'), + destinationPort: Arr::get($raw, 'dport'), + icmpType: Arr::get($raw, 'icmp-type'), + interface: Arr::get($raw, 'iface'), + logLevel: ($level = Arr::get($raw, 'log')) ? FirewallLogLevel::from($level) : null, + comment: Arr::get($raw, 'comment'), + digest: Arr::get($raw, 'digest'), + ); + } + + /** + * The PVE-shaped body for a create or update request. + * + * Null properties are omitted rather than sent empty -- an empty string + * does not clear a field in Proxmox, it just fails differently. + * + * @return array + */ + public function toPayload(): array + { + $payload = [ + 'type' => $this->direction->value, + 'action' => $this->action->value, + 'enable' => (int) $this->isEnabled, + ]; + + foreach (self::OPTIONAL_KEYS as $property => $key) { + $value = $this->{$property}; + + if ($value === null || $value === '') { + continue; + } + + $payload[$key] = $value instanceof \BackedEnum ? $value->value : $value; + } + + return $payload; + } + + /** + * PVE keys that $previous had set and this rule does not, i.e. the ones an + * update has to explicitly `delete` rather than merely omit. + * + * @return list + */ + public function clearedKeysAgainst(self $previous): array + { + $cleared = []; + + foreach (self::OPTIONAL_KEYS as $property => $key) { + $wasSet = $previous->{$property} !== null && $previous->{$property} !== ''; + $isSet = $this->{$property} !== null && $this->{$property} !== ''; + + if ($wasSet && ! $isSet) { + $cleared[] = $key; + } + } + + return $cleared; + } +} diff --git a/app/Data/Server/Proxmox/GuestAgent/GuestAgentExecStatusData.php b/app/Data/Server/Proxmox/GuestAgent/GuestAgentExecStatusData.php new file mode 100644 index 00000000000..dfddfe079ab --- /dev/null +++ b/app/Data/Server/Proxmox/GuestAgent/GuestAgentExecStatusData.php @@ -0,0 +1,35 @@ + Arr::get($data, $key, $default); + + return new self( + exited: (bool) $get('exited', false), + exitCode: $get('exitcode'), + outData: $get('out-data'), + errData: $get('err-data'), + outTruncated: (bool) $get('out-truncated', false), + errTruncated: (bool) $get('err-truncated', false), + signal: $get('signal'), + ); + } +} diff --git a/app/Data/Server/Proxmox/GuestAgent/GuestAgentFsInfoData.php b/app/Data/Server/Proxmox/GuestAgent/GuestAgentFsInfoData.php new file mode 100644 index 00000000000..55795eced0d --- /dev/null +++ b/app/Data/Server/Proxmox/GuestAgent/GuestAgentFsInfoData.php @@ -0,0 +1,28 @@ + */ + public Collection $ipAddresses, + ) {} + + public static function fromRaw(array $raw): self + { + $addresses = Arr::get($raw, 'ip-addresses', []); + + return new self( + name: Arr::get($raw, 'name', ''), + hardwareAddress: Arr::get($raw, 'hardware-address'), + ipAddresses: GuestAgentNetworkIpAddressData::collect($addresses, Collection::class), + ); + } +} diff --git a/app/Data/Server/Proxmox/GuestAgent/GuestAgentNetworkIpAddressData.php b/app/Data/Server/Proxmox/GuestAgent/GuestAgentNetworkIpAddressData.php new file mode 100644 index 00000000000..3c267381c21 --- /dev/null +++ b/app/Data/Server/Proxmox/GuestAgent/GuestAgentNetworkIpAddressData.php @@ -0,0 +1,24 @@ + Arr::get($data, $key); + + return new self( + name: $get('name'), + kernelRelease: $get('kernel-release'), + version: $get('version'), + prettyName: $get('pretty-name'), + versionId: $get('version-id'), + machine: $get('machine'), + id: $get('id'), + kernelVersion: $get('kernel-version'), + ); + } +} diff --git a/app/Data/Server/Proxmox/GuestAgent/GuestAgentUserData.php b/app/Data/Server/Proxmox/GuestAgent/GuestAgentUserData.php new file mode 100644 index 00000000000..9172217e3f0 --- /dev/null +++ b/app/Data/Server/Proxmox/GuestAgent/GuestAgentUserData.php @@ -0,0 +1,27 @@ + State::from($raw['status']), + 'powerState' => PowerState::from($raw['status']), 'uptime' => $raw['uptime'], - 'cpu_used' => $raw['cpu'], - 'memory_total' => $raw['maxmem'], - 'memory_used' => $raw['mem'], + 'cpuUsed' => $raw['cpu'], + 'memoryTotal' => $raw['maxmem'], + 'memoryUsed' => $raw['mem'], ]); } } diff --git a/app/Data/Server/Proxmox/Snapshot/SnapshotData.php b/app/Data/Server/Proxmox/Snapshot/SnapshotData.php new file mode 100644 index 00000000000..66e22d9a7bb --- /dev/null +++ b/app/Data/Server/Proxmox/Snapshot/SnapshotData.php @@ -0,0 +1,28 @@ +name, + hostname: $server->hostname, + ); + } +} diff --git a/app/Data/Server/SerialConsoleData.php b/app/Data/Server/SerialConsoleData.php new file mode 100644 index 00000000000..1614b615fa7 --- /dev/null +++ b/app/Data/Server/SerialConsoleData.php @@ -0,0 +1,29 @@ +id, + uuid: $server->uuid, + uuidShort: $server->uuid_short, + userId: $server->user_id, + nodeId: $server->node_id, + networkInterfaceId: $server->network_interface_id, + vmid: $server->vmid, + hostname: $server->hostname, + name: $server->name, + description: $server->description, + lifecycle: $server->lifecycle, + suspendedAt: $server->suspended_at, + flaggedAt: Auth::user()?->root_admin ? $server->flagged_at : null, + flagReason: Auth::user()?->root_admin ? $server->flag_reason : null, + powerState: app(GuestStateCache::class)->stateFor($server), + cpu: $server->cpu, + memory: (int) $server->memory, + disk: (int) $server->disk, + bandwidthUsage: (int) ($server->bandwidth_usage ?? 0), + backupCountLimit: $server->backup_count_limit, + backupSizeLimit: $server->backup_size_limit, + hasBackupStorage: $server->node->hasBackupStorage(), + bandwidthLimit: (int) $server->bandwidth_limit, + speedLimit: $server->speed_limit, + overagePenalty: $server->overage_penalty, + vlanTag: $server->vlan_tag, + createdAt: CarbonImmutable::parse($server->created_at), + node: Lazy::whenLoaded( + 'node', + $server, + fn () => NodeData::from($server->node), + ), + ); + } +} diff --git a/app/Data/Server/ServerDiskData.php b/app/Data/Server/ServerDiskData.php new file mode 100644 index 00000000000..1cb1a72c0ec --- /dev/null +++ b/app/Data/Server/ServerDiskData.php @@ -0,0 +1,32 @@ +id, + storageId: $disk->storage_id, + storageName: $disk->storage->name, + size: (int) $disk->size, + interface: $disk->interface, + isPrimary: (bool) $disk->is_primary, + diskIndex: $disk->disk_index, + ); + } +} diff --git a/app/Data/Server/ServerNetworkSettingsData.php b/app/Data/Server/ServerNetworkSettingsData.php new file mode 100644 index 00000000000..c47e825296d --- /dev/null +++ b/app/Data/Server/ServerNetworkSettingsData.php @@ -0,0 +1,13 @@ + */ + public array $nameservers, + ) {} +} diff --git a/app/Data/Server/ServerPresetData.php b/app/Data/Server/ServerPresetData.php new file mode 100644 index 00000000000..f2993216b68 --- /dev/null +++ b/app/Data/Server/ServerPresetData.php @@ -0,0 +1,34 @@ +uuid, + name: $preset->name, + description: $preset->description, + settings: ServerPresetSettingsData::from($preset->settings ?? []), + createdAt: CarbonImmutable::instance($preset->created_at), + updatedAt: CarbonImmutable::instance($preset->updated_at), + ); + } +} diff --git a/app/Data/Server/ServerPresetDiskData.php b/app/Data/Server/ServerPresetDiskData.php new file mode 100644 index 00000000000..988b7e9d32d --- /dev/null +++ b/app/Data/Server/ServerPresetDiskData.php @@ -0,0 +1,20 @@ + */ + public array $sshKeys, + ) {} +} diff --git a/app/Data/Server/ServerStorageData.php b/app/Data/Server/ServerStorageData.php new file mode 100644 index 00000000000..d74deaa7bd5 --- /dev/null +++ b/app/Data/Server/ServerStorageData.php @@ -0,0 +1,35 @@ +volume === '' || $disk->volume === 'none') ? null : $disk->volume; + $isCloudinit = $volume !== null && str_ends_with($volume, '-cloudinit'); + + return new self( + interface: $disk->interface->value, + media: $disk->diskMediaType, + volume: $volume, + mediaName: $isCloudinit ? null : self::mediaNameFor($disk->diskMediaType, $volume), + isCloudinitDrive: $isCloudinit, + size: $disk->size, + format: $disk->format, + isEmulatingSSD: $disk->isEmulatingSSD, + isIncludedInBackup: $disk->isIncludedInBackup, + isReadonly: $disk->isReadonly, + discardMode: $disk->discardMode, + isIOThreadEnabled: $disk->isIOThreadEnabled, + ); + } + + /** + * An ISO volume reads `storage:iso/debian-13.iso`; the part after the last + * slash is the file name the ISO library lists it under. + */ + private static function mediaNameFor(DiskMediaType $media, ?string $volume): ?string + { + if ($media !== DiskMediaType::CDROM || $volume === null) { + return null; + } + + $name = str_contains($volume, '/') ? substr(strrchr($volume, '/'), 1) : $volume; + + return $name === '' ? null : $name; + } +} diff --git a/app/Data/Storage/StorageConsumerData.php b/app/Data/Storage/StorageConsumerData.php new file mode 100644 index 00000000000..cc52a77f039 --- /dev/null +++ b/app/Data/Storage/StorageConsumerData.php @@ -0,0 +1,41 @@ +withoutWrapping()`. Nested inside a `Data` that is + * itself returned from a controller, a collection otherwise picks up the global + * `data` wrapper a second time and the payload arrives as `servers.data[]` while + * the generated TypeScript says `StorageConsumerData[]`. + */ +class StorageConsumersData extends Data +{ + public function __construct( + /** @var DataCollection */ + public DataCollection $servers, + /** @var DataCollection */ + public DataCollection $backups, + ) {} +} diff --git a/app/Data/Storage/StorageEloquentData.php b/app/Data/Storage/StorageEloquentData.php new file mode 100644 index 00000000000..ca70006c5b3 --- /dev/null +++ b/app/Data/Storage/StorageEloquentData.php @@ -0,0 +1,174 @@ + + */ + public array $sharedWith, + // What Proxmox says this storage is, recorded by the poll. Null until a + // node has reported it at least once. + public ?string $pveType, + public ?bool $pveShared, + public ?string $pveContent, + /** + * Whether committed may legitimately exceed physical usage — thin + * backends and PBS. The UI needs this to know that a large gap is + * ordinary rather than something to warn about. + */ + public bool $isThin, + // Convoy's own bookkeeping (bytes) — what it has allocated, per resource. + public int $serverUsage, + public int $backupUsage, + public int $isoUsage, + // Sum of the three above — "Allocated by Convoy". + public int $committedByConvoy, + // Whether the figures below came from a live call this request. + public bool $online, + /** + * Where the physical figures came from: `live` this request, `recorded` + * by the last poll, or `unknown` if no node has ever reported it. + * + * The page used to go blank the moment a node was unreachable, because + * live was the only source. The poll now writes the same figures, so a + * brief outage costs freshness rather than the whole panel — but only if + * the UI can say which it is showing. + */ + public string $capacitySource, + /** When the physical figures were observed. Null when never. */ + public ?CarbonImmutable $observedAt, + public ?int $physicalTotal, + public ?int $physicalUsed, + public ?int $physicalFree, + /** + * physicalUsed − committedByConvoy: the slice Convoy cannot account for. + * + * Null when there is nothing to subtract from, and null on thin or + * deduplicating backends where the subtraction is not valid — there the + * ledger legitimately exceeds physical bytes, and clamping the result at + * zero would present "no unaccounted space" as a finding rather than an + * artefact of the arithmetic. + */ + public ?int $untracked, + // What a new disk may actually consume: physicalFree − reservedBytes. + public ?int $freeForConvoy, + ) {} + + public static function fromModel( + Storage $storage, + ?StorageData $live = null, + ?Node $viewedFrom = null, + ): self { + $serverUsage = (int) ($storage->server_usage ?? 0); + $backupUsage = (int) ($storage->backup_usage ?? 0); + $isoUsage = (int) ($storage->iso_usage ?? 0); + $committed = $serverUsage + $backupUsage + $isoUsage; + $reserved = (int) ($storage->reserved_bytes ?? 0); + $isThin = StorageBackends::isThin($storage->pve_type); + + // Live if we have it, otherwise whatever the poll last wrote -- the + // viewing node's own reading when one is in scope, and the definition's + // resolved figure (freshest for shared, summed for local) when not. + // `free` is derived rather than stored: PVE gives used and total on the + // cluster rows, and total − used is the same number it would have + // reported. + $recorded = $storage->recordedCapacity($viewedFrom); + + [$source, $observedAt, $total, $used] = match (true) { + $live !== null => ['live', CarbonImmutable::now(), $live->total, $live->used], + $recorded['at'] !== null => ['recorded', $recorded['at'], $recorded['total'], $recorded['used']], + default => ['unknown', null, null, null], + }; + + $free = $total !== null ? max(0, $total - $used) : null; + + // Live reports free directly; a recorded figure derives it. Prefer the + // reported one, which accounts for filesystem overhead the subtraction + // cannot see. + $physicalFree = $live->free ?? $free; + + return new self( + id: $storage->id, + displayName: $storage->display_name, + description: $storage->description, + name: $storage->name, + size: (int) $storage->size, + reservedBytes: $storage->reserved_bytes, + storesKvm: (bool) $storage->stores_kvm, + storesLxc: (bool) $storage->stores_lxc, + storesLxcTemplates: (bool) $storage->stores_lxc_templates, + storesBackups: (bool) $storage->stores_backups, + storesIso: (bool) $storage->stores_iso, + storesSnippets: (bool) $storage->stores_snippets, + storesImport: (bool) $storage->stores_import, + backupOrder: $storage->pivot?->backup_order, + sharedWith: $storage->relationLoaded('nodes') || $viewedFrom !== null + ? $storage->nodes + ->reject(fn (Node $node) => $viewedFrom !== null && $node->is($viewedFrom)) + // Carries the id as well as the name so a list with no node + // in scope can link to each one -- a fleet page you cannot + // navigate from is a dead end. + ->map(fn (Node $node) => [ + 'id' => $node->id, + 'name' => $node->display_name ?? $node->name, + ]) + ->values() + ->all() + : [], + pveType: $storage->pve_type, + pveShared: $storage->pve_shared, + pveContent: $storage->pve_content, + isThin: $isThin, + serverUsage: $serverUsage, + backupUsage: $backupUsage, + isoUsage: $isoUsage, + committedByConvoy: $committed, + online: $live !== null, + capacitySource: $source, + observedAt: $observedAt, + physicalTotal: $total, + physicalUsed: $used, + physicalFree: $physicalFree, + untracked: $used !== null && ! $isThin ? max(0, $used - $committed) : null, + freeForConvoy: $physicalFree !== null + ? max(0, $physicalFree - $reserved) + : null, + ); + } +} diff --git a/app/Data/User/AccountCapabilitiesData.php b/app/Data/User/AccountCapabilitiesData.php new file mode 100644 index 00000000000..afc0b4a4724 --- /dev/null +++ b/app/Data/User/AccountCapabilitiesData.php @@ -0,0 +1,33 @@ + */ + public array $abilities, + /** @var list */ + public array $allowedNetworks, + public ?CarbonImmutable $lastUsedAt, + public Optional|string $plainTextToken, + // The admin who minted the token (audit). Null once that admin is deleted — the token lives on. + #[LoadRelation] + public Lazy|UserData|null $createdBy, + ) {} + + public static function fromModel(PersonalAccessToken $token, ?string $plainTextToken = null): self + { + return new self( + id: $token->id, + type: $token->type->value, + name: $token->name, + abilities: $token->abilities ?? ['*'], + allowedNetworks: $token->allowed_networks ?? [], + lastUsedAt: $token->last_used_at + ? CarbonImmutable::parse($token->last_used_at) + : null, + plainTextToken: $plainTextToken ?? Optional::create(), + createdBy: Lazy::whenLoaded( + 'createdBy', + $token, + fn () => $token->createdBy + ? UserData::from($token->createdBy) + : null, + ), + ); + } +} diff --git a/app/Data/User/AvatarCropData.php b/app/Data/User/AvatarCropData.php new file mode 100644 index 00000000000..fe0b4cd5102 --- /dev/null +++ b/app/Data/User/AvatarCropData.php @@ -0,0 +1,36 @@ +filled(['crop_x', 'crop_y', 'crop_size'])) { + return null; + } + + return new self( + x: $request->integer('crop_x'), + y: $request->integer('crop_y'), + size: $request->integer('crop_size'), + ); + } +} diff --git a/app/Data/User/OAuthConnectionData.php b/app/Data/User/OAuthConnectionData.php new file mode 100644 index 00000000000..cb0adceef24 --- /dev/null +++ b/app/Data/User/OAuthConnectionData.php @@ -0,0 +1,38 @@ +id, + provider: $connection->provider, + label: (string) config("oauth.providers.{$connection->provider}.label", Str::title($connection->provider)), + name: $connection->name, + email: $connection->email, + lastUsedAt: $connection->last_used_at ? CarbonImmutable::parse($connection->last_used_at) : null, + createdAt: CarbonImmutable::parse($connection->created_at), + ); + } +} diff --git a/app/Data/User/PasskeyData.php b/app/Data/User/PasskeyData.php new file mode 100644 index 00000000000..23083558ac4 --- /dev/null +++ b/app/Data/User/PasskeyData.php @@ -0,0 +1,32 @@ +id, + name: $passkey->name, + lastUsedAt: $passkey->last_used_at + ? CarbonImmutable::parse($passkey->last_used_at) + : null, + createdAt: CarbonImmutable::parse($passkey->created_at), + ); + } +} diff --git a/app/Data/User/SSHKeyData.php b/app/Data/User/SSHKeyData.php new file mode 100644 index 00000000000..c8fd1188dbb --- /dev/null +++ b/app/Data/User/SSHKeyData.php @@ -0,0 +1,30 @@ +id, + name: $key->name, + publicKey: $key->public_key, + createdAt: CarbonImmutable::parse($key->created_at), + ); + } +} diff --git a/app/Data/User/SessionRecordData.php b/app/Data/User/SessionRecordData.php new file mode 100644 index 00000000000..1a0483808c5 --- /dev/null +++ b/app/Data/User/SessionRecordData.php @@ -0,0 +1,34 @@ +id, + ipAddress: $record->ip_address, + userAgent: $record->user_agent, + lastActiveAt: CarbonImmutable::parse($record->last_active_at), + isCurrent: $record->session_id === $currentSessionId, + ); + } +} diff --git a/app/Data/User/UserData.php b/app/Data/User/UserData.php new file mode 100644 index 00000000000..8ed1362c0aa --- /dev/null +++ b/app/Data/User/UserData.php @@ -0,0 +1,130 @@ +id, + name: $user->name, + email: $user->email, + avatarUrl: $user->avatarUrl(), + rootAdmin: (bool) $user->root_admin, + serversCount: isset($user->servers_count) + ? (int) $user->servers_count + : Optional::create(), + createdAt: $user->created_at + ? CarbonImmutable::parse($user->created_at) + : null, + ); + } + + /** + * The signed-in account, as returned to itself: the base payload plus the policy the account + * screen reads to decide which fields to offer. + * + * Takes the resolved capabilities rather than the resolver so this stays a plain mapper, and + * so the caller is the one that decided whose policy this is. + */ + public static function forSelf(User $user, AccountCapabilitiesData $capabilities): self + { + $base = self::fromModel($user); + + $base->accountCapabilities = $capabilities; + + return $base; + } + + /** + * The whole account, for the admin's user detail page: what it owns, and every credential that + * can be used to sign in as it. + * + * Three queries — the counts, the resource aggregate, and the last login — rather than loading + * four collections to call `count()` on each. + */ + public static function detail(User $user): self + { + $user->loadCount([ + 'servers', + 'sshKeys', + 'passkeys', + 'oauthConnections', + // `apiKeys`, not `tokens`: the relation already excludes application tokens, which + // belong to the panel rather than to the person and are invisible on this page. + 'apiKeys', + ]); + + /* + * Derived from the audit log rather than a column on `users`. The panel already records + * every successful sign-in with its IP and keeps those rows forever + * ({@see AuditEvent::retention()}), so a column would be a second, weaker copy of a fact + * already stored — weaker because it cannot say where the login came from without a second + * column, and because nothing would backfill it for accounts that signed in before it + * existed. + */ + $lastLogin = AuditLog::query() + ->where('event', '=', AuditEvent::AUTH_LOGIN_SUCCEEDED) + ->whereMorphedTo('actor', $user) + ->latest('id') + ->first(['created_at', 'ip']); + + $base = self::fromModel($user); + + $base->apiKeysCount = (int) $user->api_keys_count; + $base->sshKeysCount = (int) $user->ssh_keys_count; + $base->passkeysCount = (int) $user->passkeys_count; + $base->oauthConnectionsCount = (int) $user->oauth_connections_count; + // Fortify's check, not `two_factor_secret !== null`: with confirmation required, a setup + // the user abandoned halfway has a secret and is not enabled. + $base->twoFactorEnabled = $user->hasEnabledTwoFactorAuthentication(); + $base->lastLoginAt = $lastLogin?->created_at; + $base->lastLoginIp = $lastLogin?->ip; + $base->resources = UserResourcesData::forUser($user); + + return $base; + } +} diff --git a/app/Data/User/UserInviteData.php b/app/Data/User/UserInviteData.php new file mode 100644 index 00000000000..0a6e84df974 --- /dev/null +++ b/app/Data/User/UserInviteData.php @@ -0,0 +1,24 @@ +where('user_id', '=', $user->id) + ->selectRaw('COUNT(*) AS servers_count') + ->selectRaw('COUNT(DISTINCT node_id) AS nodes_count') + ->selectRaw('SUM(CASE WHEN suspended_at IS NOT NULL THEN 1 ELSE 0 END) AS suspended_count') + ->selectRaw( + 'SUM(CASE WHEN lifecycle <> ? THEN 1 ELSE 0 END) AS unbuilt_count', + [ServerLifecycle::READY->value], + ) + ->selectRaw('SUM(CASE WHEN cpu >= 0 THEN cpu ELSE 0 END) AS cpu_total') + ->selectRaw('SUM(CASE WHEN memory >= 0 THEN memory ELSE 0 END) AS memory_total') + ->selectRaw('SUM(CASE WHEN disk >= 0 THEN disk ELSE 0 END) AS disk_total') + ->selectRaw('SUM(CASE WHEN bandwidth_usage >= 0 THEN bandwidth_usage ELSE 0 END) AS bandwidth_usage_total') + ->selectRaw('SUM(CASE WHEN bandwidth_limit >= 0 THEN bandwidth_limit ELSE 0 END) AS bandwidth_limit_total') + ->selectRaw('SUM(CASE WHEN bandwidth_limit < 0 THEN 1 ELSE 0 END) AS unmetered_count') + ->first(); + + $unmetered = (int) ($totals?->unmetered_count ?? 0); + + return new self( + serversCount: (int) ($totals?->servers_count ?? 0), + suspendedCount: (int) ($totals?->suspended_count ?? 0), + unbuiltCount: (int) ($totals?->unbuilt_count ?? 0), + nodesCount: (int) ($totals?->nodes_count ?? 0), + cpu: (int) ($totals?->cpu_total ?? 0), + memory: (int) ($totals?->memory_total ?? 0) * self::BYTES_PER_MIB, + disk: (int) ($totals?->disk_total ?? 0) * self::BYTES_PER_MIB, + bandwidthUsage: (int) ($totals?->bandwidth_usage_total ?? 0) * self::BYTES_PER_MIB, + bandwidthLimit: $unmetered > 0 + ? null + : (int) ($totals?->bandwidth_limit_total ?? 0) * self::BYTES_PER_MIB, + ); + } +} diff --git a/app/Enums/Activity/Status.php b/app/Enums/Activity/Status.php index 38eeb9cfc54..2a4fd6a93dd 100644 --- a/app/Enums/Activity/Status.php +++ b/app/Enums/Activity/Status.php @@ -1,6 +1,6 @@ ..` and are a **stable API** — they are written to the database, + * returned by the client and admin audit endpoints, and matched exhaustively by the frontend copy + * map. Renaming a value orphans every historical row that carries it, so treat these as immutable + * once shipped; the human-readable wording lives on the frontend precisely so it can change freely + * without touching stored data. + * + * This enum is transformed into a TypeScript string union in `resources/scripts/types/generated.d.ts`, + * which is what makes the frontend's `Record` copy map fail to compile when a case + * is added here without matching wording. + * + * Adding an event: add the case, and only touch {@see self::retention()} or {@see self::visibility()} + * if it needs something other than the default (pruned on the standard window, visible to clients). + */ +enum AuditEvent: string +{ + // ----------------------------------------------------------------------------------------- + // Authentication. Subject is the User being authenticated (null on a failed login where no + // account matched). These are the events an operator reaches for after a compromise. + // ----------------------------------------------------------------------------------------- + // Recorded from Laravel's own auth events rather than call sites, because the controllers + // behind them belong to Fortify. Deliberately only three: a passkey login, a completed + // two-factor challenge and an identity re-confirmation all end in Auth::login(), so giving + // them their own cases would double-count a single sign-in. + case AUTH_LOGIN_SUCCEEDED = 'auth.login.succeeded'; + case AUTH_LOGIN_FAILED = 'auth.login.failed'; + case AUTH_LOGOUT = 'auth.logout'; + case AUTH_INVITE_ACCEPTED = 'auth.invite.accepted'; + + // ----------------------------------------------------------------------------------------- + // Account and credential management. Subject is the User. + // ----------------------------------------------------------------------------------------- + case ACCOUNT_PROFILE_UPDATED = 'account.profile.updated'; + case ACCOUNT_AVATAR_UPDATED = 'account.avatar.updated'; + case ACCOUNT_PASSWORD_UPDATED = 'account.password.updated'; + case ACCOUNT_TWO_FACTOR_ENABLED = 'account.two-factor.enabled'; + case ACCOUNT_TWO_FACTOR_CONFIRMED = 'account.two-factor.confirmed'; + case ACCOUNT_TWO_FACTOR_DISABLED = 'account.two-factor.disabled'; + case ACCOUNT_RECOVERY_CODES_REGENERATED = 'account.recovery-codes.regenerated'; + case ACCOUNT_PASSKEY_CREATED = 'account.passkey.created'; + case ACCOUNT_PASSKEY_RENAMED = 'account.passkey.renamed'; + case ACCOUNT_PASSKEY_DELETED = 'account.passkey.deleted'; + case ACCOUNT_SSH_KEY_CREATED = 'account.ssh-key.created'; + case ACCOUNT_SSH_KEY_DELETED = 'account.ssh-key.deleted'; + case ACCOUNT_API_KEY_CREATED = 'account.api-key.created'; + case ACCOUNT_API_KEY_DELETED = 'account.api-key.deleted'; + case ACCOUNT_SESSION_REVOKED = 'account.session.revoked'; + case ACCOUNT_OAUTH_CONNECTION_DELETED = 'account.oauth-connection.deleted'; + + // ----------------------------------------------------------------------------------------- + // Client-side server actions. Subject is the Server. These are the bulk of #53. + // ----------------------------------------------------------------------------------------- + // One event carrying the PowerCommand as a property, rather than a case per signal. There are + // seven signals and an admin mirror of each; enumerating them would mean fourteen cases and a + // catalog change every time PowerCommand grows. The frontend renders this one key through an + // exhaustive map over PowerCommand, which is itself a generated TS union. + case SERVER_POWER_SENT = 'server.power.sent'; + case SERVER_REINSTALLED = 'server.reinstalled'; + case SERVER_INSTALLATION_RETRIED = 'server.installation.retried'; + case SERVER_RENAMED = 'server.renamed'; + case SERVER_CONSOLE_SESSION_CREATED = 'server.console.session-created'; + case SERVER_CONSOLE_DISPLAY_ENABLED = 'server.console.display-enabled'; + case SERVER_CONSOLE_SERIAL_ENABLED = 'server.console.serial-enabled'; + case SERVER_BACKUP_CREATED = 'server.backup.created'; + case SERVER_BACKUP_DELETED = 'server.backup.deleted'; + case SERVER_BACKUP_RESTORED = 'server.backup.restored'; + case SERVER_FIREWALL_OPTIONS_UPDATED = 'server.firewall.options-updated'; + case SERVER_FIREWALL_RULE_CREATED = 'server.firewall.rule-created'; + case SERVER_FIREWALL_RULE_UPDATED = 'server.firewall.rule-updated'; + case SERVER_FIREWALL_RULE_DELETED = 'server.firewall.rule-deleted'; + case SERVER_FIREWALL_RULE_MOVED = 'server.firewall.rule-moved'; + case SERVER_AUTH_SETTINGS_UPDATED = 'server.settings.auth-updated'; + case SERVER_BOOT_ORDER_UPDATED = 'server.settings.boot-order-updated'; + case SERVER_NETWORK_SETTINGS_UPDATED = 'server.settings.network-updated'; + case SERVER_MEDIA_MOUNTED = 'server.media.mounted'; + case SERVER_MEDIA_UNMOUNTED = 'server.media.unmounted'; + + // ----------------------------------------------------------------------------------------- + // Administrative actions on a server. Subject is the Server, so these surface in the owning + // client's activity feed too — deliberately, since they are things done *to* their server. + // ----------------------------------------------------------------------------------------- + case ADMIN_SERVER_CREATED = 'admin.server.created'; + case ADMIN_SERVER_UPDATED = 'admin.server.updated'; + case ADMIN_SERVER_DELETED = 'admin.server.deleted'; + case ADMIN_SERVER_POWER_SENT = 'admin.server.power-sent'; + case ADMIN_SERVER_BUILD_UPDATED = 'admin.server.build-updated'; + case ADMIN_SERVER_SUSPENDED = 'admin.server.suspended'; + case ADMIN_SERVER_UNSUSPENDED = 'admin.server.unsuspended'; + case ADMIN_SERVER_DISK_CREATED = 'admin.server.disk-created'; + case ADMIN_SERVER_DISK_UPDATED = 'admin.server.disk-updated'; + case ADMIN_SERVER_DISK_DELETED = 'admin.server.disk-deleted'; + // Recorded by the placement reconciler when PVE moved the guest (HA + // recovery, migration) and Convoy followed. Actor is the SystemActor. + case ADMIN_SERVER_REHOMED = 'admin.server.rehomed'; + case ADMIN_BACKUP_DELETED = 'admin.backup.deleted'; + + // ----------------------------------------------------------------------------------------- + // Infrastructure. Subject is the Node or the nested resource. Never client-visible. + // ----------------------------------------------------------------------------------------- + case ADMIN_NODE_CREATED = 'admin.node.created'; + case ADMIN_NODE_UPDATED = 'admin.node.updated'; + case ADMIN_NODE_DELETED = 'admin.node.deleted'; + case ADMIN_ISO_CREATED = 'admin.iso.created'; + case ADMIN_ISO_UPDATED = 'admin.iso.updated'; + case ADMIN_ISO_DELETED = 'admin.iso.deleted'; + case ADMIN_ISO_UPLOADED = 'admin.iso.uploaded'; + case ADMIN_NODE_INTERFACE_CREATED = 'admin.node.interface-created'; + case ADMIN_NODE_INTERFACE_UPDATED = 'admin.node.interface-updated'; + case ADMIN_NODE_INTERFACE_DELETED = 'admin.node.interface-deleted'; + case ADMIN_NODE_VLAN_CREATED = 'admin.node.vlan-created'; + case ADMIN_NODE_VLAN_UPDATED = 'admin.node.vlan-updated'; + case ADMIN_NODE_VLAN_DELETED = 'admin.node.vlan-deleted'; + case ADMIN_NODE_STORAGE_CREATED = 'admin.node.storage-created'; + case ADMIN_NODE_STORAGE_UPDATED = 'admin.node.storage-updated'; + case ADMIN_NODE_STORAGE_DELETED = 'admin.node.storage-deleted'; + case ADMIN_NODE_STORAGE_BACKUP_ORDER_UPDATED = 'admin.node.storage-backup-order-updated'; + // The operator cleared the cluster identity tripwire (see ClusterIdentityService). + case ADMIN_CLUSTER_UNFLAGGED = 'admin.cluster.unflagged'; + case ADMIN_LOCATION_CREATED = 'admin.location.created'; + case ADMIN_LOCATION_UPDATED = 'admin.location.updated'; + case ADMIN_LOCATION_DELETED = 'admin.location.deleted'; + case ADMIN_RELAY_CREATED = 'admin.relay.created'; + case ADMIN_RELAY_UPDATED = 'admin.relay.updated'; + case ADMIN_RELAY_DELETED = 'admin.relay.deleted'; + case ADMIN_ANCHOR_ENROLLMENT_ROTATED = 'admin.anchor.enrollment-rotated'; + case ADMIN_ANCHOR_ENROLLMENT_KEY_CREATED = 'admin.anchor.enrollment-key-created'; + case ADMIN_ANCHOR_ENROLLMENT_KEY_REVOKED = 'admin.anchor.enrollment-key-revoked'; + case ADMIN_ANCHOR_ENROLLMENT_KEY_DELETED = 'admin.anchor.enrollment-key-deleted'; + case ADMIN_ANCHOR_APPROVED = 'admin.anchor.approved'; + case ADMIN_ANCHOR_REJECTED = 'admin.anchor.rejected'; + + /* + * Nobody at a keyboard did this -- a machine presented a key and the panel + * acted on it. That is carried by the row having no actor, not by the area: + * the prefixes are a closed, frontend-matched set, and keeping this one + * under `admin.anchor` means filtering by that area returns the whole story + * of an installation, self-enrollment included. + */ + case ADMIN_ANCHOR_SELF_ENROLLED = 'admin.anchor.self-enrolled'; + + // ----------------------------------------------------------------------------------------- + // IP address management. Subject is the block group, block, or address. + // ----------------------------------------------------------------------------------------- + case ADMIN_ADDRESS_BLOCK_GROUP_CREATED = 'admin.address-block-group.created'; + case ADMIN_ADDRESS_BLOCK_GROUP_UPDATED = 'admin.address-block-group.updated'; + case ADMIN_ADDRESS_BLOCK_GROUP_DELETED = 'admin.address-block-group.deleted'; + case ADMIN_ADDRESS_BLOCK_GROUP_NODE_ATTACHED = 'admin.address-block-group.node-attached'; + case ADMIN_ADDRESS_BLOCK_GROUP_NODE_DETACHED = 'admin.address-block-group.node-detached'; + case ADMIN_ADDRESS_BLOCK_CREATED = 'admin.address-block.created'; + case ADMIN_ADDRESS_BLOCK_UPDATED = 'admin.address-block.updated'; + case ADMIN_ADDRESS_BLOCK_DELETED = 'admin.address-block.deleted'; + case ADMIN_ADDRESS_GENERATED = 'admin.address.generated'; + case ADMIN_ADDRESS_UPDATED = 'admin.address.updated'; + case ADMIN_ADDRESS_DELETED = 'admin.address.deleted'; + case ADMIN_ADDRESS_RESERVED = 'admin.address.reserved'; + case ADMIN_ADDRESS_UNRESERVED = 'admin.address.unreserved'; + + // ----------------------------------------------------------------------------------------- + // Users, tokens and panel configuration. Subject is the User, token, or null for settings. + // ----------------------------------------------------------------------------------------- + case ADMIN_USER_CREATED = 'admin.user.created'; + case ADMIN_USER_UPDATED = 'admin.user.updated'; + case ADMIN_USER_DELETED = 'admin.user.deleted'; + case ADMIN_USER_SSO_TOKEN_GENERATED = 'admin.user.sso-token-generated'; + case ADMIN_USER_INVITED = 'admin.user.invited'; + case ADMIN_USER_INVITE_REVOKED = 'admin.user.invite-revoked'; + case ADMIN_TOKEN_CREATED = 'admin.token.created'; + case ADMIN_TOKEN_UPDATED = 'admin.token.updated'; + case ADMIN_TOKEN_DELETED = 'admin.token.deleted'; + case ADMIN_SETTINGS_ACCOUNT_UPDATED = 'admin.settings.account-updated'; + case ADMIN_SETTINGS_ANCHOR_UPDATED = 'admin.settings.anchor-updated'; + case ADMIN_SETTINGS_BANDWIDTH_UPDATED = 'admin.settings.bandwidth-updated'; + case ADMIN_SETTINGS_MAIL_UPDATED = 'admin.settings.mail-updated'; + case ADMIN_SETTINGS_MAIL_TESTED = 'admin.settings.mail-tested'; + + // ----------------------------------------------------------------------------------------- + // Presets and templates. Subject is the preset, group, or template. + // ----------------------------------------------------------------------------------------- + case ADMIN_SERVER_PRESET_CREATED = 'admin.server-preset.created'; + case ADMIN_SERVER_PRESET_UPDATED = 'admin.server-preset.updated'; + case ADMIN_SERVER_PRESET_DELETED = 'admin.server-preset.deleted'; + case ADMIN_IMAGE_GROUP_CREATED = 'admin.image-group.created'; + case ADMIN_IMAGE_GROUP_UPDATED = 'admin.image-group.updated'; + case ADMIN_IMAGE_GROUP_DELETED = 'admin.image-group.deleted'; + case ADMIN_IMAGE_CREATED = 'admin.image.created'; + case ADMIN_IMAGE_UPDATED = 'admin.image.updated'; + case ADMIN_IMAGE_DELETED = 'admin.image.deleted'; + case ADMIN_IMAGE_VERSION_CREATED = 'admin.image-version.created'; + case ADMIN_IMAGE_VERSION_UPDATED = 'admin.image-version.updated'; + case ADMIN_IMAGE_VERSION_DELETED = 'admin.image-version.deleted'; + case ADMIN_IMAGE_UPLOADED = 'admin.image.uploaded'; + + /** + * How long entries for this event survive. Defaults to the configured prune window; the listed + * exceptions are kept forever because they are what a compromise investigation needs and they + * are far too low-volume to be worth reclaiming. + */ + public function retention(): AuditRetention + { + return match ($this) { + self::AUTH_LOGIN_SUCCEEDED, + self::AUTH_LOGIN_FAILED, + self::AUTH_LOGOUT, + self::ACCOUNT_PROFILE_UPDATED, + self::ACCOUNT_PASSWORD_UPDATED, + self::ACCOUNT_TWO_FACTOR_ENABLED, + self::ACCOUNT_TWO_FACTOR_CONFIRMED, + self::ACCOUNT_TWO_FACTOR_DISABLED, + self::ACCOUNT_RECOVERY_CODES_REGENERATED, + self::ACCOUNT_PASSKEY_CREATED, + self::ACCOUNT_PASSKEY_RENAMED, + self::ACCOUNT_PASSKEY_DELETED, + self::ACCOUNT_SSH_KEY_CREATED, + self::ACCOUNT_SSH_KEY_DELETED, + self::ACCOUNT_API_KEY_CREATED, + self::ACCOUNT_API_KEY_DELETED, + self::ACCOUNT_SESSION_REVOKED, + self::ACCOUNT_OAUTH_CONNECTION_DELETED, + self::ADMIN_USER_CREATED, + self::ADMIN_USER_UPDATED, + self::ADMIN_USER_DELETED, + self::ADMIN_USER_SSO_TOKEN_GENERATED, + self::ADMIN_TOKEN_CREATED, + self::ADMIN_TOKEN_UPDATED, + self::ADMIN_TOKEN_DELETED, + self::ADMIN_SERVER_DELETED, + self::ADMIN_NODE_DELETED, + self::ADMIN_ANCHOR_ENROLLMENT_KEY_CREATED, + self::ADMIN_ANCHOR_ENROLLMENT_KEY_REVOKED, + self::ADMIN_ANCHOR_ENROLLMENT_KEY_DELETED, + self::ADMIN_ANCHOR_APPROVED, + self::ADMIN_ANCHOR_REJECTED, + self::ADMIN_ANCHOR_SELF_ENROLLED => AuditRetention::FOREVER, + default => AuditRetention::STANDARD, + }; + } + + /** + * Whether this event may be shown to a non-admin who can see the subject. + * + * Most events need no entry here: infrastructure events are hidden in practice because their + * subject is a Node or a token that no client can reach, and server events are things the + * owner is entitled to see. The exceptions below are events whose subject *is* client-reachable + * but whose existence should not be. + */ + public function visibility(): AuditVisibility + { + return match ($this) { + // Reveals that the panel minted a token capable of impersonating the user. + self::ADMIN_USER_SSO_TOKEN_GENERATED => AuditVisibility::ADMIN_ONLY, + // Names physical nodes; which host a VM lands on is infrastructure + // detail a client has no lever over and no need to see. + self::ADMIN_SERVER_REHOMED => AuditVisibility::ADMIN_ONLY, + default => AuditVisibility::CLIENT, + }; + } + + /** Every event that the pruner must never delete. */ + public static function retainedForever(): array + { + return array_values(array_filter( + self::cases(), + fn (self $event) => $event->retention() === AuditRetention::FOREVER, + )); + } +} diff --git a/app/Enums/Audit/AuditRetention.php b/app/Enums/Audit/AuditRetention.php new file mode 100644 index 00000000000..ddb94bcd07a --- /dev/null +++ b/app/Enums/Audit/AuditRetention.php @@ -0,0 +1,17 @@ + 'STARTTLS', + self::SSL => 'Implicit TLS', + self::NONE => 'None', + }; + } + + /** The port operators expect for this mode, used to prefill the form. */ + public function defaultPort(): int + { + return match ($this) { + self::SSL => 465, + self::TLS => 587, + self::NONE => 25, + }; + } +} diff --git a/app/Enums/Network/AddressState.php b/app/Enums/Network/AddressState.php new file mode 100644 index 00000000000..74554d0c505 --- /dev/null +++ b/app/Enums/Network/AddressState.php @@ -0,0 +1,18 @@ + self::TLS_ERROR, + 'TLS' => self::TLS_ERROR, + 'SSL' => self::TLS_ERROR, + + /** Broad network errors */ + 'cURL error 28' => self::TIMEOUT, + 'hostname lookup' => self::DNS_ERROR, + 'Could not resolve host' => self::DNS_ERROR, + 'Connection refused' => self::CONNECTION_REFUSED, + + /** Token errors */ + 'no such token' => self::TOKEN_INVALID, + 'invalid token value' => self::TOKEN_INVALID, + 'Permission check failed' => self::TOKEN_MISSING_PERMISSIONS, + ]; + + public static function classify(string $message): self + { + foreach (self::MAPPINGS as $needle => $errorType) { + if (Str::contains($message, $needle)) { + return $errorType; + } + } + + return self::OTHER; + } +} diff --git a/app/Enums/Node/NodeStatus.php b/app/Enums/Node/NodeStatus.php new file mode 100644 index 00000000000..b191aec5d7a --- /dev/null +++ b/app/Enums/Node/NodeStatus.php @@ -0,0 +1,23 @@ + 'images', // KVM disk images + self::LXC => 'rootdir', // LXC container data (root directory) + self::LXC_TEMPLATES => 'vztmpl', // LXC templates + self::BACKUPS => 'backup', // Backup files + self::ISO => 'iso', // ISO image files + self::SNIPPETS => 'snippets', // Snippet files (e.g., cloud-init configs) + self::IMPORT => 'import', // Importable disk images (qcow2/raw); off by default in PVE + }; + } + + /** + * Read PVE's comma-separated content list into the `stores_*` columns. + * + * Which content a storage accepts is Proxmox's answer, not an operator's: + * it is declared in `/etc/pve/storage.cfg` and enforced by PVE itself, so a + * tick box here could only ever agree with it or be wrong. Every caller that + * turns a content list into flags goes through this, so the panel cannot + * disagree with itself about what `vztmpl` means. + * + * Matching is per token rather than by substring: the list is delimited, and + * a substring test would let a backend named after one content type answer + * for another. + * + * @return array keyed by the model's column names + */ + public static function flagsFor(?string $content): array + { + $tokens = collect(explode(',', (string) $content)) + ->map(fn (string $token) => trim($token)) + ->filter() + ->all(); + + return collect(self::cases()) + ->mapWithKeys(fn (self $case) => [ + $case->toModelAttributeName() => in_array($case->toProxmoxString(), $tokens, true), + ]) + ->all(); + } + + /** + * Get the corresponding attribute name on the App\Models\Storage model. + * This is needed for validation rules that check the model's capabilities. + * + * @return string The corresponding boolean attribute name (e.g., 'stores_kvm'). + */ + public function toModelAttributeName(): string + { + return match ($this) { + self::KVM => 'stores_kvm', + self::LXC => 'stores_lxc', + self::LXC_TEMPLATES => 'stores_lxc_templates', + self::BACKUPS => 'stores_backups', + self::ISO => 'stores_iso', + self::SNIPPETS => 'stores_snippets', + self::IMPORT => 'stores_import', + }; + } +} diff --git a/app/Enums/Server/AuthenticationType.php b/app/Enums/Server/AuthenticationType.php index 919072d9604..4900cce10b3 100644 --- a/app/Enums/Server/AuthenticationType.php +++ b/app/Enums/Server/AuthenticationType.php @@ -1,6 +1,6 @@ code mappings, checked in order. Matched against the raw + * failure text pulled from the Proxmox task log. Deliberately loose: a + * miss just falls through to OTHER, which is always safe to show. + */ + private const MAPPINGS = [ + /** Storage / quota exhaustion */ + 'no space left' => self::STORAGE_EXCEEDED, + 'not enough space' => self::STORAGE_EXCEEDED, + 'quota exceeded' => self::STORAGE_EXCEEDED, + 'storage is full' => self::STORAGE_EXCEEDED, + + /** Timeouts (incl. the orphan-prune message) */ + 'timed out' => self::TIMEOUT, + 'timeout' => self::TIMEOUT, + 'did not complete in time' => self::TIMEOUT, + ]; + + /** + * Classify a raw backup failure message into a stable, client-safe code. + */ + public static function classify(string $message): self + { + foreach (self::MAPPINGS as $needle => $code) { + if (Str::contains($message, $needle, ignoreCase: true)) { + return $code; + } + } + + return self::OTHER; + } +} diff --git a/app/Enums/Server/BackupCompressionType.php b/app/Enums/Server/BackupCompressionType.php index fd7d13d3b1b..036453d2d08 100644 --- a/app/Enums/Server/BackupCompressionType.php +++ b/app/Enums/Server/BackupCompressionType.php @@ -1,6 +1,6 @@ 4, // IDE0-IDE3 + 'sata' => 6, // SATA0-SATA5 + 'scsi' => 31, // SCSI0-SCSI30 + 'virtio' => 16, // VIRTIO0-VIRTIO15 + 'efidisk' => 1, // EFIDISK0 only + 'tpmstate' => 1, // TPMSTATE0 only + default => throw new \InvalidArgumentException("Unknown interface type: {$interfaceType}"), + }; + } + + /** + * Get the base interface type (ide, sata, scsi, virtio, efidisk, tpmstate) + */ + public function getBaseType(): string + { + if (preg_match('/^([a-z]+)\d+$/', $this->value, $matches)) { + return $matches[1]; + } + + throw new \RuntimeException("Could not determine base type for {$this->value}"); + } + + /** + * Get the slot number for this interface + */ + public function getSlot(): int + { + if (preg_match('/^[a-z]+(\d+)$/', $this->value, $matches)) { + return (int) $matches[1]; + } + + throw new \RuntimeException("Could not determine slot number for {$this->value}"); + } + + /** + * Check if a given interface type has available slots + * + * @param string $interfaceType Base interface type (ide, sata, scsi, virtio, etc.) + * @param array $usedSlots Array of slot numbers already in use + * @return bool True if there are available slots + */ + public static function hasAvailableSlots(string $interfaceType, array $usedSlots): bool + { + $maxSlots = self::getMaxDevices($interfaceType); + + // If we have fewer used slots than max, there's availability + return count($usedSlots) < $maxSlots; + } + + /** + * Get the next available slot for a given interface type + * + * @param string $interfaceType Base interface type (ide, sata, scsi, virtio, etc.) + * @param array $usedSlots Array of slot numbers already in use + * @return int|null The next available slot or null if none available + */ + public static function getNextAvailableSlot(string $interfaceType, array $usedSlots): ?int + { + $maxSlots = self::getMaxDevices($interfaceType); + + // Find the first unused slot + for ($i = 0; $i < $maxSlots; $i++) { + if (! in_array($i, $usedSlots)) { + return $i; + } + } + + return null; // No available slots + } + + /** + * Check if a specified interface and slot is valid + */ + public static function isValid(string $interfaceType, int $slot): bool + { + try { + $maxSlots = self::getMaxDevices($interfaceType); + + return $slot >= 0 && $slot < $maxSlots; + } catch (\InvalidArgumentException $e) { + return false; + } + } } diff --git a/app/Enums/Server/Firewall/FirewallLogLevel.php b/app/Enums/Server/Firewall/FirewallLogLevel.php new file mode 100644 index 00000000000..83ebf1ae540 --- /dev/null +++ b/app/Enums/Server/Firewall/FirewallLogLevel.php @@ -0,0 +1,22 @@ + self::ANY, + // '2' => self::SIZE_2MB, + // '1024' => self::SIZE_1GB, + // default => throw new \InvalidArgumentException("Invalid huge pages setting: {$value}") + // }; + // } +} diff --git a/app/Enums/Server/MetricParameter.php b/app/Enums/Server/MetricParameter.php deleted file mode 100644 index 31dbc7ded74..00000000000 --- a/app/Enums/Server/MetricParameter.php +++ /dev/null @@ -1,9 +0,0 @@ - $case->value); + } +} diff --git a/app/Enums/Server/OperatingSystemType.php b/app/Enums/Server/OperatingSystemType.php new file mode 100644 index 00000000000..4ae9825d2c4 --- /dev/null +++ b/app/Enums/Server/OperatingSystemType.php @@ -0,0 +1,97 @@ + self::OTHER, + 'wxp' => self::WINDOWS_XP, + 'w2k' => self::WINDOWS_2000, + 'w2k3' => self::WINDOWS_2003, + 'w2k8' => self::WINDOWS_2008, + 'wvista' => self::WINDOWS_VISTA, + 'win7' => self::WINDOWS_7, + 'win8' => self::WINDOWS_8, + 'win10' => self::WINDOWS_10, + 'win11' => self::WINDOWS_11, + 'l24' => self::LINUX_24, + 'l26' => self::LINXUX_26, + 'solaris' => self::SOLARIS, + default => self::UNKNOWN, + }; + } +} diff --git a/app/Enums/Server/OveragePenaltyAction.php b/app/Enums/Server/OveragePenaltyAction.php new file mode 100644 index 00000000000..d90ce4b58e3 --- /dev/null +++ b/app/Enums/Server/OveragePenaltyAction.php @@ -0,0 +1,16 @@ + true, + default => false, + }; + } +} diff --git a/app/Enums/Server/State.php b/app/Enums/Server/State.php deleted file mode 100644 index 0602347f18d..00000000000 --- a/app/Enums/Server/State.php +++ /dev/null @@ -1,14 +0,0 @@ -model->event === $event; - } - - public function actor(): ?Model - { - return $this->isSystem() ? null : $this->model->actor; - } - - public function isServerEvent(): bool - { - return Str::startsWith($this->model->event, 'server:'); - } - - public function isUserEvent(): bool - { - return Str::startsWith($this->model->event, 'user:'); - } - - public function isSystem() - { - // @phpstan-ignore-next-line - return is_null($this->model->actor_id); - } -} diff --git a/app/Exceptions/ConvoyException.php b/app/Exceptions/ConvoyException.php index 03f715472d8..8bd37684821 100644 --- a/app/Exceptions/ConvoyException.php +++ b/app/Exceptions/ConvoyException.php @@ -1,9 +1,7 @@ level; - } - - public function getStatusCode(): int - { - return Response::HTTP_BAD_REQUEST; - } - - public function getHeaders(): array - { - return []; - } - - /** - * Render the exception to the user by adding a flashed message to the session - * and then redirecting them back to the page that they came from. If the - * request originated from an API hit, return the error in JSONAPI spec format. - */ - public function render(Request $request): JsonResponse|RedirectResponse - { - if ($request->expectsJson()) { - return response()->json(Handler::toArray($this), $this->getStatusCode(), $this->getHeaders()); - } - - return redirect()->back()->withInput(); - } - - /** - * Log the exception to the logs using the defined error level only if the previous - * exception is set. - * - * @throws Throwable - */ - public function report() - { - if (! $this->getPrevious() instanceof Exception || ! Handler::isReportable($this->getPrevious())) { - return null; - } - - try { - $logger = Container::getInstance()->make(LoggerInterface::class); - } catch (Exception) { - throw $this->getPrevious(); - } - - return $logger->{$this->getErrorLevel()}($this->getPrevious()); - } -} diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index d610a11bcd0..c9afb22607c 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -1,11 +1,11 @@ shouldReport($exception); + return (new self(Container::getInstance()))->shouldReport($exception); } /** diff --git a/app/Exceptions/HasErrorCode.php b/app/Exceptions/HasErrorCode.php new file mode 100644 index 00000000000..725f537a59b --- /dev/null +++ b/app/Exceptions/HasErrorCode.php @@ -0,0 +1,16 @@ +connectionError->value; + } +} diff --git a/app/Exceptions/Http/Passkey/InvalidAuthenticatorAttestationResponse.php b/app/Exceptions/Http/Passkey/InvalidAuthenticatorAttestationResponse.php new file mode 100644 index 00000000000..a0354dddb89 --- /dev/null +++ b/app/Exceptions/Http/Passkey/InvalidAuthenticatorAttestationResponse.php @@ -0,0 +1,23 @@ +isSuspended()) { - $message = 'This server is currently suspended and the functionality requested is unavailable.'; - } elseif (! $server->isInstalled()) { - $message = 'This server has not yet completed its installation process, please try again later.'; - } - - parent::__construct($message, $previous); - } -} diff --git a/app/Exceptions/Http/Server/ServerUnavailableException.php b/app/Exceptions/Http/Server/ServerUnavailableException.php new file mode 100644 index 00000000000..4f400ab8619 --- /dev/null +++ b/app/Exceptions/Http/Server/ServerUnavailableException.php @@ -0,0 +1,30 @@ +isSuspended()) { + $message = 'This server is currently suspended and the functionality requested is unavailable.'; + } elseif (! $server->isInstalled()) { + $message = 'This server has not yet completed its installation process, please try again later.'; + } + + parent::__construct($message, $previous); + } +} diff --git a/app/Exceptions/Model/DataValidationException.php b/app/Exceptions/Model/DataValidationException.php index 6b0ffa29e11..8f371f23925 100644 --- a/app/Exceptions/Model/DataValidationException.php +++ b/app/Exceptions/Model/DataValidationException.php @@ -1,12 +1,12 @@ prepareMessage($response), $response->status()); + } + + protected function prepareMessage(Response $response): string + { + $summary = Message::bodySummary($response->toPsrResponse()); + $reason = $response->reason(); + + return is_null($summary) ? $reason : $reason .= ":\n{$summary}\n"; + } +} diff --git a/app/Exceptions/Repository/Proxmox/ProxmoxConnectionException.php b/app/Exceptions/Repository/Proxmox/ProxmoxConnectionException.php deleted file mode 100644 index 4a21a0e7580..00000000000 --- a/app/Exceptions/Repository/Proxmox/ProxmoxConnectionException.php +++ /dev/null @@ -1,15 +0,0 @@ -reason() . PHP_EOL . $exception->getMessage() . PHP_EOL . $exception->getTraceAsString(), $exception->getCode(), $exception); - } -} diff --git a/app/Exceptions/Repository/RecordNotFoundException.php b/app/Exceptions/Repository/RecordNotFoundException.php deleted file mode 100644 index 37bb9b3edaa..00000000000 --- a/app/Exceptions/Repository/RecordNotFoundException.php +++ /dev/null @@ -1,25 +0,0 @@ -uuid_short, + rtrim((string) $server->flag_reason, '.').'.', + )); + } + + public function errorCode(): string + { + return 'server_flagged'; + } +} diff --git a/app/Extensions/Lcobucci/JWT/Validation/Clock.php b/app/Extensions/Lcobucci/JWT/Validation/Clock.php index b11c51c5d22..b41a3a8ffa7 100644 --- a/app/Extensions/Lcobucci/JWT/Validation/Clock.php +++ b/app/Extensions/Lcobucci/JWT/Validation/Clock.php @@ -1,17 +1,18 @@ date = $date ?? CarbonImmutable::now(); } diff --git a/app/Extensions/Spatie/Data/CarbonIntervalTransformer.php b/app/Extensions/Spatie/Data/CarbonIntervalTransformer.php new file mode 100644 index 00000000000..22e494e6639 --- /dev/null +++ b/app/Extensions/Spatie/Data/CarbonIntervalTransformer.php @@ -0,0 +1,21 @@ +total('seconds'); + } +} diff --git a/app/Extensions/Spatie/Data/Casts/CommaSeparatedArrayCast.php b/app/Extensions/Spatie/Data/Casts/CommaSeparatedArrayCast.php new file mode 100644 index 00000000000..8d89a2c595e --- /dev/null +++ b/app/Extensions/Spatie/Data/Casts/CommaSeparatedArrayCast.php @@ -0,0 +1,19 @@ + decimal MB/s; (string) trims a whole number to "100" and keeps + // fractional rates like "1.5". Proxmox accepts a floating point number. + return (string) ((int) $value / self::BYTES_PER_MEGABYTE); + } +} diff --git a/app/Extensions/Spatie/Data/Proxmox/MapsProxmoxProperties.php b/app/Extensions/Spatie/Data/Proxmox/MapsProxmoxProperties.php new file mode 100644 index 00000000000..88fb1cd4295 --- /dev/null +++ b/app/Extensions/Spatie/Data/Proxmox/MapsProxmoxProperties.php @@ -0,0 +1,102 @@ +` or the disk + * volume) is not covered here — it is DTO-specific and handled by the DTO. + */ +trait MapsProxmoxProperties +{ + /** @var array> */ + private static array $proxmoxSpecCache = []; + + /** + * Parse the `key=value` tail into a map of DTO property name => typed value, + * alongside the leftover pairs we don't explicitly model. + * + * @param array $pairs + * @return array{0: array, 1: array} [mapped, leftover] + */ + protected static function mapProxmoxProperties(array $pairs): array + { + $mapped = []; + $known = []; + + foreach (self::proxmoxPropertySpecs() as $spec) { + $known[] = $spec->key; + + if (array_key_exists($spec->key, $pairs)) { + $mapped[$spec->property] = $spec->parse($pairs[$spec->key]); + } + } + + return [$mapped, Arr::except($pairs, $known)]; + } + + /** + * Emit the modeled tail keys as PVE `key=value` pairs, skipping null (i.e. + * unset) properties so partial updates never resend an empty value. + * + * @return array + */ + protected function toProxmoxProperties(): array + { + $pairs = []; + + foreach (self::proxmoxPropertySpecs() as $spec) { + $value = $this->{$spec->property}; + + if ($value === null) { + continue; + } + + $emitted = $spec->emit($value); + + if ($emitted !== null) { + $pairs[$spec->key] = $emitted; + } + } + + return $pairs; + } + + /** + * @return list + */ + private static function proxmoxPropertySpecs(): array + { + return self::$proxmoxSpecCache[static::class] ??= self::resolveProxmoxPropertySpecs(); + } + + /** + * @return list + */ + private static function resolveProxmoxPropertySpecs(): array + { + $constructor = (new ReflectionClass(static::class))->getConstructor(); + + $specs = []; + foreach ($constructor?->getParameters() ?? [] as $parameter) { + $attribute = $parameter->getAttributes(ProxmoxProperty::class)[0] ?? null; + + if ($attribute === null) { + continue; + } + + $specs[] = ProxmoxPropertySpec::fromParameter($parameter, $attribute->newInstance()); + } + + return $specs; + } +} diff --git a/app/Extensions/Spatie/Data/Proxmox/PropertyList.php b/app/Extensions/Spatie/Data/Proxmox/PropertyList.php new file mode 100644 index 00000000000..a1b4d156652 --- /dev/null +++ b/app/Extensions/Spatie/Data/Proxmox/PropertyList.php @@ -0,0 +1,64 @@ +[,=]* + * + * The first comma-segment (the "head") is positional and DTO-specific — for a + * NIC it is `model[=macaddr]`, for a disk it is the backing volume — so callers + * handle it explicitly. Everything after it is an order-independent bag of + * `key=value` pairs, which this codec parses and rebuilds. + */ +class PropertyList +{ + /** + * Split a raw property-list string into its positional head and the + * associative `key=value` tail. + * + * @return array{0: string, 1: array} [head, pairs] + */ + public static function explode(string $raw): array + { + $segments = explode(',', trim($raw)); + $head = trim((string) array_shift($segments)); + + $pairs = []; + foreach ($segments as $segment) { + if (blank($segment)) { + continue; + } + + $kv = explode('=', $segment, 2); + if (count($kv) === 2) { + $pairs[trim($kv[0])] = trim($kv[1]); + } + } + + return [$head, $pairs]; + } + + /** + * Rebuild a property-list string from a positional head and a set of + * `key=value` pairs. Null values are skipped so absent keys never leak an + * empty pair into the emitted config. + * + * @param array $pairs + */ + public static function implode(string $head, array $pairs): string + { + $segments = [$head]; + + foreach ($pairs as $key => $value) { + if ($value === null) { + continue; + } + + $segments[] = "{$key}={$value}"; + } + + return implode(',', $segments); + } +} diff --git a/app/Extensions/Spatie/Data/Proxmox/ProxmoxProperty.php b/app/Extensions/Spatie/Data/Proxmox/ProxmoxProperty.php new file mode 100644 index 00000000000..dd6a13ffe04 --- /dev/null +++ b/app/Extensions/Spatie/Data/Proxmox/ProxmoxProperty.php @@ -0,0 +1,33 @@ +|null $cast Explicit cast for + * values that are not a plain int, string, or backed enum. int, + * string, and backed-enum properties are handled automatically. + */ + public function __construct( + public string $key, + public ?string $cast = null, + ) {} +} diff --git a/app/Extensions/Spatie/Data/Proxmox/ProxmoxPropertyCast.php b/app/Extensions/Spatie/Data/Proxmox/ProxmoxPropertyCast.php new file mode 100644 index 00000000000..5f28b8545c5 --- /dev/null +++ b/app/Extensions/Spatie/Data/Proxmox/ProxmoxPropertyCast.php @@ -0,0 +1,26 @@ +getType(); + $typeName = $type instanceof ReflectionNamedType ? $type->getName() : 'string'; + + $cast = $meta->cast !== null ? new $meta->cast : null; + $enumClass = null; + + if ($cast === null) { + if (enum_exists($typeName)) { + $enumClass = $typeName; + } elseif ($typeName === 'bool') { + throw new LogicException(sprintf( + 'Proxmox bool property "%s" must declare a cast (e.g. PveBooleanCast); PVE encodes booleans as 1/0.', + $parameter->getName(), + )); + } + } + + return new self($parameter->getName(), $meta->key, $cast, $enumClass, $typeName); + } + + public function parse(string $value): mixed + { + if ($this->cast !== null) { + return $this->cast->parse($value); + } + + if ($this->enumClass !== null) { + return ($this->enumClass)::from($value); + } + + return match ($this->typeName) { + 'int' => (int) $value, + 'float' => (float) $value, + default => $value, + }; + } + + public function emit(mixed $value): ?string + { + if ($this->cast !== null) { + return $this->cast->emit($value); + } + + if ($this->enumClass !== null) { + return $value->value; + } + + return (string) $value; + } +} diff --git a/app/Facades/Activity.php b/app/Facades/Activity.php deleted file mode 100644 index 9e2bc4307d1..00000000000 --- a/app/Facades/Activity.php +++ /dev/null @@ -1,14 +0,0 @@ -addressBlocks()) + ->withAddressStateCounts() + ->defaultSort('-id') + ->allowedFilters( + AllowedFilter::custom('*', new FiltersAddressBlockWildcard), + 'name', + 'description', + AllowedFilter::exact('version'), + AllowedFilter::exact('base_ip'), + AllowedFilter::exact('gateway'), + AllowedFilter::exact('mac_address'), + AllowedFilter::exact('prefix_length_to'), + AllowedFilter::exact('prefix_length_from'), + ) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($blocks, AddressBlockData::class); + } + + public function show(AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock) + { + $addressBlock->loadCount(AddressBlock::addressStateCounts()); + + return AddressBlockData::from($addressBlock); + } + + public function store(StoreAddressBlockRequest $request, AddressBlockGroup $addressBlockGroup) + { + $block = $addressBlockGroup->addressBlocks()->create($request->validated()); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_CREATED, + subject: $block, + properties: ['base_ip' => $block->base_ip, 'group' => $addressBlockGroup->name], + ); + + return AddressBlockData::from($block); + } + + /** + * @throws Throwable + */ + public function update( + UpdateAddressBlockRequest $request, + AddressBlockGroup $addressBlockGroup, + AddressBlock $addressBlock, + ) { + $this->connection->transaction( + function () use ($request, $addressBlock) { + if ( + $addressBlock->base_ip !== $request->string('base_ip')->toString() || + $addressBlock->prefix_length_from !== $request->integer('prefix_length_from') || + $addressBlock->prefix_length_to !== $request->integer('prefix_length_to') + ) { + $addressBlock->addresses()->delete(); + } + + $addressBlock->update($request->validated()); + + if ( + $addressBlock->mac_address !== $request->input('mac_address') || + $addressBlock->gateway !== $request->input('gateway') + ) { + dispatch(new BatchSyncNetworkSettingsJob($addressBlock)); + } + }, + ); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_UPDATED, + subject: $addressBlock, + properties: [ + 'base_ip' => $addressBlock->base_ip, + 'changed' => array_keys($addressBlock->getChanges()), + ], + ); + + return AddressBlockData::from($addressBlock); + } + + public function destroy(AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock): Response + { + Gate::authorize('delete', $addressBlock); + + $baseIp = $addressBlock->base_ip; + + $addressBlock->delete(); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_DELETED, + subject: $addressBlock, + properties: ['base_ip' => $baseIp], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/AddressBlockGroupController.php b/app/Http/Controllers/Admin/AddressBlockGroupController.php new file mode 100644 index 00000000000..777e2628d26 --- /dev/null +++ b/app/Http/Controllers/Admin/AddressBlockGroupController.php @@ -0,0 +1,281 @@ +withCount('addressBlocks', 'nodes') + ->withAddressStateCounts(denseOnly: true) + // The pool's total size is the sum of its blocks' geometry, so the rows come along + // rather than costing a query per pool to add them up. + ->with('addressBlocks:id,address_block_group_id,base_ip,prefix_length_from,prefix_length_to') + ->defaultSort('-id') + ->allowedFilters( + AllowedFilter::custom( + '*', new FiltersAddressBlockGroupWildcard, + ), + AllowedFilter::callback( + 'node_id', + function (Builder $query, $value): void { + $nodeIds = is_array($value) ? $value : [$value]; + + $query->whereHas( + 'networkInterfaces', + function (Builder $query) use ($nodeIds): void { + $query->whereIn('node_id', $nodeIds); + }, + ); + }, + ), + 'name', + 'description', + ) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($groups, AddressBlockGroupData::class); + } + + /** + * The IPAM index's headline figures, across every pool. + * + * Deliberately not derived from the page of pools the table is showing: the moment there is a + * second page, a total that quietly means "of the rows you can see" is wrong, and a wrong + * headline is worse than none. One pass over the blocks (there are tens, not millions) carries + * both the roll-up and the "which block is about to fill up" answer the tile needs. + */ + public function summary() + { + $blocks = AddressBlock::query()->withAddressStateCounts()->get(); + + $generated = $assigned = $reserved = $system = $available = 0; + $totalUnits = 0; + $denseBlocks = 0; + $sparseBlocks = 0; + $nearlyFull = []; + + foreach ($blocks as $block) { + $capacity = AddressCapacityData::forBlock($block); + + // A sparse block contributes neither a denominator nor a numerator: counting its + // minted addresses against the sized blocks' total would read past 100% full. + if ($capacity->totalUnits === null) { + $sparseBlocks++; + + continue; + } + + $denseBlocks++; + $generated += $capacity->generatedCount; + $assigned += $capacity->assignedCount; + $reserved += $capacity->reservedCount; + $system += $capacity->systemCount; + $available += $capacity->availableCount; + + $totalUnits += $capacity->totalUnits; + + // A block with nothing generated has no ratio, so it cannot be "nearly full" — it is + // not set up yet, which is a different problem and a different message. + $usable = $capacity->totalUnits - $capacity->systemCount; + + if ($capacity->generatedCount < 1 || $usable < 1) { + continue; + } + + $percent = (($capacity->assignedCount + $capacity->reservedCount) / $usable) * 100; + + if ($percent >= 90) { + $nearlyFull[] = new NearlyFullBlockData( + id: $block->id, + addressBlockGroupId: $block->address_block_group_id, + label: $block->base_ip.'/'.$block->prefix_length_from, + percent: round($percent, 1), + ); + } + } + + usort($nearlyFull, fn (NearlyFullBlockData $a, NearlyFullBlockData $b) => $b->percent <=> $a->percent); + + return new IpamSummaryData( + capacity: new AddressCapacityData( + totalUnits: $denseBlocks > 0 ? $totalUnits : null, + isSparse: $denseBlocks === 0 && $sparseBlocks > 0, + generatedCount: $generated, + assignedCount: $assigned, + reservedCount: $reserved, + systemCount: $system, + availableCount: $available, + sparseBlockCount: $sparseBlocks, + ), + poolsCount: AddressBlockGroup::query()->count(), + blocksCount: $blocks->count(), + nodesCount: NetworkInterface::query() + ->whereHas('addressBlockGroups') + ->distinct() + ->count('node_id'), + blocksNearlyFull: count($nearlyFull), + fullestBlock: $nearlyFull[0] ?? null, + ); + } + + public function show(AddressBlockGroup $addressBlockGroup) + { + $addressBlockGroup->loadCount('addressBlocks', 'nodes'); + $addressBlockGroup->loadCount(AddressBlockGroup::addressStateCounts(denseOnly: true)); + $addressBlockGroup->load('addressBlocks:id,address_block_group_id,base_ip,prefix_length_from,prefix_length_to'); + + return AddressBlockGroupData::from($addressBlockGroup); + } + + public function store(AddressBlockGroupRequest $request) + { + $addressBlockGroup = AddressBlockGroup::create($request->validated()); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_GROUP_CREATED, + subject: $addressBlockGroup, + properties: ['name' => $addressBlockGroup->name], + ); + + return AddressBlockGroupData::from($addressBlockGroup); + } + + public function update(AddressBlockGroupRequest $request, AddressBlockGroup $addressBlockGroup) + { + $addressBlockGroup->update($request->validated()); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_GROUP_UPDATED, + subject: $addressBlockGroup, + properties: [ + 'name' => $addressBlockGroup->name, + 'changed' => array_keys($addressBlockGroup->getChanges()), + ], + ); + + return AddressBlockGroupData::from($addressBlockGroup); + } + + public function destroy(AddressBlockGroup $addressBlockGroup): Response + { + Gate::authorize('delete', $addressBlockGroup); + + $name = $addressBlockGroup->name; + + $addressBlockGroup->delete(); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_GROUP_DELETED, + subject: $addressBlockGroup, + properties: ['name' => $name], + ); + + return response()->noContent(); + } + + public function getAttachedNodes(Request $request, AddressBlockGroup $addressBlockGroup) + { + $interfaces = QueryBuilder::for($addressBlockGroup->networkInterfaces()) + ->with(['node' => function ($query) { + $query->withCount('servers'); + }]) + ->defaultSort('-id') + ->allowedFilters([ + AllowedFilter::callback('*', function (Builder $query, $value) { + $query->where('name', 'LIKE', "%$value%") + ->orWhereHas('node', function (Builder $query) use ($value) { + $query->where('fqdn', 'LIKE', "%$value%") + ->orWhere('display_name', 'LIKE', "%$value%"); + }); + }), + AllowedFilter::exact('node_id'), + ]) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($interfaces, NetworkInterfaceData::class); + } + + public function attachNode(AttachNodeRequest $request, AddressBlockGroup $addressBlockGroup) + { + $addressBlockGroup->networkInterfaces()->syncWithoutDetaching([ + $request->input('network_interface_id'), + ]); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_GROUP_NODE_ATTACHED, + subject: $addressBlockGroup, + properties: ['network_interface_id' => (int) $request->input('network_interface_id')], + ); + + return response()->json([], 201); + } + + public function detachNode(DetachNodeRequest $request, AddressBlockGroup $addressBlockGroup, Node $node): Response + { + $interfaceIds = $node->networkInterfaces()->pluck('id'); + $addressBlockGroup->networkInterfaces()->detach($interfaceIds); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_BLOCK_GROUP_NODE_DETACHED, + subject: $addressBlockGroup, + properties: ['node' => $node->name], + ); + + return response()->noContent(); + } + + public function getCompatibleServers(Request $request, AddressBlockGroup $addressBlockGroup) + { + $servers = QueryBuilder::for(Server::query()) + ->with(['node' => function (BelongsTo $query): void { + $query->withCount('servers'); + }]) + ->whereHas('node.networkInterfaces.addressBlockGroups', function (Builder $query) use ($addressBlockGroup): void { + $query->where('address_block_groups.id', $addressBlockGroup->id); + }) + ->defaultSort('-id') + ->allowedFilters([ + AllowedFilter::custom('*', new FiltersServerWildcard), + AllowedFilter::exact('node_id'), + AllowedFilter::exact('user_id'), + 'name', + ]) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($servers, ServerData::class); + } +} diff --git a/app/Http/Controllers/Admin/AddressController.php b/app/Http/Controllers/Admin/AddressController.php new file mode 100644 index 00000000000..8e3028ec3e0 --- /dev/null +++ b/app/Http/Controllers/Admin/AddressController.php @@ -0,0 +1,402 @@ +addresses()) + ->with('server', 'addressBlock') + // Address order, not insertion order. A list of a subnet that opens at .255 and counts + // down is the reverse of how anyone reads a subnet; the inet column sorts natively. + ->defaultSort('ip') + ->allowedFilters( + /* + * The search box on this screen is typed at partially — ".88", "203.0.113." — so an + * exact match answers nothing an operator actually asks. `host()` renders the inet + * column back to its bare address string, which is what LIKE needs; inet itself has + * no LIKE operator. + */ + AllowedFilter::callback('ip', function (Builder $query, $value): void { + $value = is_array($value) ? reset($value) : $value; + + if ($value === null || $value === '') { + return; + } + + $query->whereRaw('host(ip) LIKE ?', ['%'.$value.'%']); + }), + AllowedFilter::exact('server_id')->nullable(), + /* + * The four states an operator sees, not the three the column stores: a system + * reservation is a reserved row the panel made and no one can release, so it + * filters as its own thing. Split exactly the way CountsAddressStates counts them, + * so a facet's count and the rows it returns can never disagree. + */ + AllowedFilter::callback('state', function (Builder $query, $value): void { + $tokens = array_filter( + (array) $value, + fn ($token) => $token !== null && $token !== '', + ); + + if ($tokens === []) { + return; + } + + $query->where(function (Builder $outer) use ($tokens): void { + foreach ($tokens as $token) { + $outer->orWhere(function (Builder $inner) use ($token): void { + match ($token) { + 'assigned' => $inner->where('state', AddressState::Assigned), + 'available' => $inner->where('state', AddressState::Available), + 'system' => $inner + ->where('state', AddressState::Reserved) + ->where('state_reason', AddressStateReason::System), + 'reserved' => $inner + ->where('state', AddressState::Reserved) + ->where(fn (Builder $reason) => $reason + ->whereNull('state_reason') + ->orWhere('state_reason', '!=', AddressStateReason::System)), + // An unrecognised token matches nothing. A filter that silently + // widens the result set is worse than one that returns none. + default => $inner->whereRaw('1 = 0'), + }; + }); + } + }); + }), + ) + ->paginate(min($request->query('per_page', 50), 100))->appends( + $request->query(), + ); + + return PaginationMeta::paginate($addresses, IpamAddressData::class); + } + + public function generate(AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock) + { + $result = $this->generateAddressesAction->execute($addressBlock); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_GENERATED, + subject: $addressBlock, + properties: ['base_ip' => $addressBlock->base_ip], + ); + + return GeneratedAddressesData::from($result); + } + + public function update(UpdateAddressRequest $request, AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock, Address $address) + { + $validated = $request->validated(); + + $this->connection->transaction(function () use ($address, $validated) { + $oldServerId = $address->server_id; + + // Keep state in lock-step with the manual assignment (reserved addresses can't reach + // here — UpdateAddressRequest rejects assigning them). + if (array_key_exists('server_id', $validated)) { + $validated['state'] = filled($validated['server_id']) + ? AddressState::Assigned + : AddressState::Available; + $validated['state_reason'] = null; + } + + $address->update($validated); + + if (array_key_exists('server_id', $validated) && $oldServerId !== $validated['server_id']) { + if (filled($oldServerId)) { + $oldServer = Server::find($oldServerId); + if ($oldServer) { + dispatch(new SyncNetworkSettingsJob($oldServer)); + } + } + + if (filled($validated['server_id'])) { + $newServer = Server::find($validated['server_id']); + if ($newServer) { + dispatch(new SyncNetworkSettingsJob($newServer)); + } + } + } + + Audit::record( + AuditEvent::ADMIN_ADDRESS_UPDATED, + subject: $address, + properties: [ + 'address' => $address->ip, + 'changed' => array_keys($address->getChanges()), + ], + ); + }); + + $address->load('server', 'addressBlock'); + + return IpamAddressData::from($address); + } + + public function reserve(AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock, Address $address) + { + if ($address->state !== AddressState::Available) { + throw new AddressNotAvailableException; + } + + $address->update([ + 'state' => AddressState::Reserved, + 'state_reason' => AddressStateReason::Admin, + ]); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_RESERVED, + subject: $address, + properties: ['address' => $address->ip], + ); + + $address->load('server', 'addressBlock'); + + return IpamAddressData::from($address); + } + + public function unreserve(AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock, Address $address) + { + if ($address->state !== AddressState::Reserved) { + throw new AddressNotReservedException; + } + + // Network / broadcast / gateway are reserved by the panel, not by an operator — freeing them + // would let the allocator hand a structural address to a VM. + if ($address->isSystemReserved()) { + throw new AddressReservedBySystemException; + } + + $address->update(['state' => AddressState::Available, 'state_reason' => null]); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_UNRESERVED, + subject: $address, + properties: ['address' => $address->ip], + ); + + $address->load('server', 'addressBlock'); + + return IpamAddressData::from($address); + } + + /** + * The block's whole address space, in address order, one entry per allocatable unit. + * + * The list answers "what is this address"; a paginated table cannot answer "where is the next + * free run", which is the question a /24 is actually opened with. This returns every unit — + * including the ones with no address row yet — so the UI can draw the space instead of asking + * the operator to page through it. + * + * Units are placed by `unitIndexOf`, not by row order: generation writes in address order, but + * one deletion would shift every later cell if position were inferred from the sequence. + */ + public function map(AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock) + { + $totalUnits = $addressBlock->totalUnits(); + + if ($addressBlock->isSparse() || $totalUnits === null) { + return (new AddressMapData(sparse: true, tooLarge: false, totalUnits: null, units: []))->toArray(); + } + + if ($totalUnits > AddressMapData::MAX_UNITS) { + return (new AddressMapData( + sparse: false, + tooLarge: true, + totalUnits: $totalUnits, + units: [], + ))->toArray(); + } + + // Every unit starts as a real position with no record behind it; the materialized rows are + // then dropped onto their own indices. + $units = []; + + for ($index = 0; $index < $totalUnits; $index++) { + $units[$index] = new AddressMapUnitData( + index: $index, + state: 'ungenerated', + // The unit is a real position whether or not a row exists for it, so it gets its + // address either way — the map labels its rows from these. + ip: $addressBlock->unitAddressAt($index), + addressId: null, + serverName: null, + ); + } + + $addressBlock->addresses()->with('server:id,name')->chunkById(1000, function ($addresses) use (&$units, $addressBlock, $totalUnits): void { + foreach ($addresses as $address) { + $index = $addressBlock->unitIndexOf($address->ip); + + // An address outside the block's current geometry (the block was edited under it) + // has no cell to sit in. Leaving it out beats drawing it in the wrong place. + if ($index === null || $index < 0 || $index >= $totalUnits) { + continue; + } + + $units[$index] = new AddressMapUnitData( + index: $index, + state: match (true) { + $address->state === AddressState::Assigned => 'assigned', + $address->isSystemReserved() => 'system', + $address->state === AddressState::Reserved => 'reserved', + default => 'available', + }, + ip: $address->ip, + addressId: $address->id, + serverName: $address->server?->name, + ); + } + }); + + return (new AddressMapData( + sparse: false, + tooLarge: false, + totalUnits: $totalUnits, + units: array_values($units), + ))->toArray(); + } + + /** + * Reserve, release or delete a selection of addresses in one request. + * + * Reserving `.2`–`.10` for infrastructure was nine trips through a row menu, and nine audit + * entries. The rules are the single-address ones, applied by skipping rather than throwing: a + * selection made by hand out of a table will contain rows the action does not apply to, and + * rejecting the whole batch because one of them is system-reserved makes the action unusable. + * What was skipped comes back in the result so the UI can say so. + */ + public function bulk(BulkAddressRequest $request, AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock) + { + $action = $request->validated('action'); + + // Scoped to the block in the URL, so an id from another block cannot be reached by + // guessing it into the body. + $addresses = $addressBlock->addresses() + ->whereIn('id', $request->validated('ids')) + ->get(); + + $eligible = $addresses->filter(fn (Address $address) => match ($action) { + 'reserve' => $address->state === AddressState::Available, + 'release' => $address->state === AddressState::Reserved && ! $address->isSystemReserved(), + // Deleting an address out from under a running server breaks its networking. The + // single-address route allows it deliberately (one address, one decision); doing it to + // a whole selection is a different risk, so assigned addresses are left alone here. + 'delete' => $address->state !== AddressState::Assigned, + default => false, + }); + + $this->connection->transaction(function () use ($action, $eligible, $addressBlock): void { + $ids = $eligible->pluck('id'); + + if ($ids->isEmpty()) { + return; + } + + match ($action) { + 'reserve' => $addressBlock->addresses()->whereIn('id', $ids)->update([ + 'state' => AddressState::Reserved, + 'state_reason' => AddressStateReason::Admin, + ]), + 'release' => $addressBlock->addresses()->whereIn('id', $ids)->update([ + 'state' => AddressState::Available, + 'state_reason' => null, + ]), + 'delete' => $addressBlock->addresses()->whereIn('id', $ids)->delete(), + default => null, + }; + + /* + * One entry for the batch rather than one per address: the operator performed a single + * action, and a log that reads as thousands of separate decisions hides that. + * + * The addresses themselves are listed only while the list is still worth reading. A + * drag across a whole block would otherwise write tens of thousands of characters into + * a properties column nobody can scan; past that, the range says the same thing. + */ + $addresses = $eligible->pluck('ip'); + + Audit::record( + match ($action) { + 'reserve' => AuditEvent::ADMIN_ADDRESS_RESERVED, + 'release' => AuditEvent::ADMIN_ADDRESS_UNRESERVED, + default => AuditEvent::ADMIN_ADDRESS_DELETED, + }, + subject: $addressBlock, + properties: $addresses->count() <= self::AUDIT_ADDRESS_LIMIT + ? ['count' => $ids->count(), 'addresses' => $addresses->all()] + : [ + 'count' => $ids->count(), + 'first' => $addresses->first(), + 'last' => $addresses->last(), + ], + ); + }); + + return new BulkAddressResultData( + action: $action, + affected: $eligible->count(), + skipped: $addresses->count() - $eligible->count(), + ); + } + + public function destroy(AddressBlockGroup $addressBlockGroup, AddressBlock $addressBlock, Address $address): Response + { + $this->connection->transaction(function () use ($address) { + $ip = $address->ip; + + $address->delete(); + + Audit::record( + AuditEvent::ADMIN_ADDRESS_DELETED, + subject: $address, + properties: ['address' => $ip], + ); + + if ($address->server) { + dispatch(new SyncNetworkSettingsJob($address->server)); + } + }); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/AddressPools/AddressController.php b/app/Http/Controllers/Admin/AddressPools/AddressController.php deleted file mode 100644 index 5f287fc98e1..00000000000 --- a/app/Http/Controllers/Admin/AddressPools/AddressController.php +++ /dev/null @@ -1,168 +0,0 @@ -addresses()) - ->with('server') - ->defaultSort('-id') - ->allowedFilters( - [ - AllowedFilter::exact('address'), - AllowedFilter::exact( - 'type', - ), - AllowedFilter::custom( - '*', - new FiltersAddressWildcard(), - ), - AllowedFilter::exact('server_id')->nullable(), - ], - ) - ->paginate(min($request->query('per_page', 50), 999999))->appends( - $request->query(), - ); - - return fractal($addresses, new AddressTransformer())->parseIncludes($request->include) - ->respond(); - } - - public function store(StoreAddressRequest $request, AddressPool $addressPool) - { - $data = $request->validated(); - - if ($data['is_bulk_action']) { - $this->bulkAddressCreationService->handle( - type : AddressType::from($data['type']), - from : $data['starting_address'], - to : $data['ending_address'], - poolId : $addressPool->id, - serverId : $data['server_id'], - cidr : $data['cidr'], - gateway : $data['gateway'], - macAddress: $data['mac_address'], - ); - - if (!is_null($request->server_id)) { - SyncNetworkSettings::dispatch($request->integer('server_id')); - } - - return $this->returnNoContent(); - } - - /** @var Address $address */ - $address = $this->connection->transaction(function () use ($data, $addressPool) { - $address = $addressPool->addresses()->create([ - ...$data, - 'address_pool_id' => $addressPool->id, - ]); - - if ($data['server_id']) { - try { - $this->networkService->syncSettings($address->server); - } catch (ProxmoxConnectionException) { - throw new ServiceUnavailableHttpException( - message: "Server {$address->server->uuid} failed to sync network settings.", - ); - } - } - - return $address; - }); - - return fractal($address, new AddressTransformer())->parseIncludes($request->include) - ->respond(); - } - - public function update( - UpdateAddressRequest $request, AddressPool $addressPool, Address $address, - ) - { - $address = $this->connection->transaction(function () use ($request, $address) { - $oldLinkedServer = $address->server; - - $address->update($request->validated()); - - $address->load('server'); // update the server relationship - - try { - // Detach old server - if ($oldLinkedServer) { - $this->networkService->syncSettings($oldLinkedServer); - } - - // Attach new server - if ($address->server) { - $this->networkService->syncSettings($address->server); - } - } catch (ProxmoxConnectionException) { - if ($oldLinkedServer && !$address->server) { - throw new ServiceUnavailableHttpException( - message: "Server {$oldLinkedServer->uuid} failed to sync network settings.", - ); - } elseif (!$oldLinkedServer && $address->server) { - throw new ServiceUnavailableHttpException( - message: "Server {$address->server->uuid} failed to sync network settings.", - ); - } elseif ($oldLinkedServer && $address->server) { - throw new ServiceUnavailableHttpException( - message: "Servers {$oldLinkedServer->uuid} and {$address->server->uuid} failed to sync network settings.", - ); - } - } - - return $address; - }); - - return fractal($address, new AddressTransformer())->parseIncludes($request->include) - ->respond(); - } - - public function destroy(AddressPool $addressPool, Address $address) - { - $this->connection->transaction(function () use ($address) { - $address->delete(); - - if ($address->server) { - try { - $this->networkService->syncSettings($address->server); - } catch (ProxmoxConnectionException) { - throw new ServiceUnavailableHttpException( - message: "Server {$address->server->uuid} failed to sync network settings.", - ); - } - } - }); - - return $this->returnNoContent(); - } -} diff --git a/app/Http/Controllers/Admin/AddressPools/AddressPoolController.php b/app/Http/Controllers/Admin/AddressPools/AddressPoolController.php deleted file mode 100644 index 6e79cbdd614..00000000000 --- a/app/Http/Controllers/Admin/AddressPools/AddressPoolController.php +++ /dev/null @@ -1,92 +0,0 @@ -withCount(['addresses', 'nodes']) - ->defaultSort('-id') - ->allowedFilters( - ['name', AllowedFilter::custom( - '*', new FiltersAddressPoolWildcard(), - )], - ) - ->paginate(min($request->query('per_page', 50), 100))->appends( - $request->query(), - ); - - return fractal($addressPools, new AddressPoolTransformer())->respond(); - } - - public function show(AddressPool $addressPool) - { - $addressPool->loadCount(['addresses', 'nodes']); - - return fractal($addressPool, new AddressPoolTransformer())->respond(); - } - - public function getAttachedNodes(Request $request, AddressPool $addressPool) - { - $nodes = QueryBuilder::for($addressPool->nodes()) - ->withCount('servers') - ->allowedFilters( - ['name', 'fqdn', AllowedFilter::exact( - 'location_id', - ), AllowedFilter::custom('*', new FiltersNodeWildcard())], - ) - ->paginate(min($request->query('per_page', 50), 100))->appends( - $request->query(), - ); - - return fractal($nodes, new NodeTransformer())->respond(); - } - - public function store(StoreAddressPoolRequest $request) - { - $pool = AddressPool::create($request->safe()->except('node_ids')); - $pool->nodes()->attach($request->node_ids); - $pool->loadCount(['addresses', 'nodes']); - - return fractal($pool, new AddressPoolTransformer())->respond(); - } - - public function update(UpdateAddressPoolRequest $request, AddressPool $addressPool) - { - $addressPool->update($request->safe()->except('node_ids')); - $addressPool->nodes()->sync($request->node_ids); - $addressPool->loadCount(['addresses', 'nodes']); - - return fractal($addressPool, new AddressPoolTransformer())->respond(); - } - - public function destroy(AddressPool $addressPool) - { - $addressPool->loadCount('nodes'); - - if ($addressPool->nodes_count > 0) { - throw new AccessDeniedHttpException( - 'This address pool cannot be deleted while still allocated to nodes.', - ); - } - - $addressPool->delete(); - - return $this->returnNoContent(); - } -} diff --git a/app/Http/Controllers/Admin/AnchorEnrollmentController.php b/app/Http/Controllers/Admin/AnchorEnrollmentController.php new file mode 100644 index 00000000000..3d83f9d0022 --- /dev/null +++ b/app/Http/Controllers/Admin/AnchorEnrollmentController.php @@ -0,0 +1,122 @@ +with('enrollmentKey:id,name') + ->defaultSort('-id') + ->allowedFilters(['name', AllowedFilter::exact('mode')]) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($enrollments, AnchorEnrollmentQueueData::class); + } + + public function show(AnchorEnrollment $anchorEnrollment) + { + return AnchorEnrollmentQueueData::fromModel( + $anchorEnrollment->loadMissing('enrollmentKey'), + $this->approval->suggestions($anchorEnrollment), + ); + } + + /** + * Let the machine in, as whatever it enrolled as. + * + * The operator supplies only what the host could not know or must not + * decide: which location it belongs to, how the panel reaches it, and (until + * the agent mints its own) the Proxmox credentials. Everything else is + * carried over from what it reported. + */ + public function approve(ApproveAnchorEnrollmentRequest $request, AnchorEnrollment $anchorEnrollment) + { + $name = $anchorEnrollment->name; + $hostname = $anchorEnrollment->reported('hostname'); + + if ($anchorEnrollment->mode === AnchorMode::RELAY) { + $relay = $this->approval->approveRelay($anchorEnrollment, $request->validated()); + + Audit::record( + AuditEvent::ADMIN_ANCHOR_APPROVED, + subject: $relay, + properties: ['name' => $relay->name, 'mode' => 'relay', 'hostname' => $hostname], + ); + + return RelayData::from($relay->loadCount('nodes')); + } + + $node = $this->approval->approveNode($anchorEnrollment, $request->validated()); + + // The scheduled poll would get there within a minute anyway; polling now + // means the node's status and cluster scope are known while the operator + // is still looking at the page they approved it from. + PollNodeStatusJob::dispatch($node->id); + + Audit::record( + AuditEvent::ADMIN_ANCHOR_APPROVED, + subject: $node, + properties: [ + 'name' => $node->display_name, + 'mode' => 'agent', + 'enrolled_as' => $name, + 'hostname' => $hostname, + ], + ); + + return NodeData::from($node->append(['memory_allocated'])->loadCount('servers')); + } + + /** + * Turn a machine away. + * + * Deleting the row is the whole remediation: the agent's credential stops + * resolving, so it can neither heartbeat nor open anything. The audit row is + * what remains, which is the part worth keeping. + */ + public function destroy(AnchorEnrollment $anchorEnrollment) + { + $properties = [ + 'name' => $anchorEnrollment->name, + 'mode' => $anchorEnrollment->mode->value, + 'hostname' => $anchorEnrollment->reported('hostname'), + 'source_ip' => $anchorEnrollment->reported('observed_source_ip'), + ]; + + $anchorEnrollment->delete(); + + Audit::record( + AuditEvent::ADMIN_ANCHOR_REJECTED, + subject: $anchorEnrollment, + properties: $properties, + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/AnchorEnrollmentKeyController.php b/app/Http/Controllers/Admin/AnchorEnrollmentKeyController.php new file mode 100644 index 00000000000..8115151ed69 --- /dev/null +++ b/app/Http/Controllers/Admin/AnchorEnrollmentKeyController.php @@ -0,0 +1,120 @@ +with('createdBy') + ->defaultSort('-id') + ->allowedFilters([ + 'name', + AllowedFilter::exact('mode'), + // Status is derived from three columns and the clock, so it + // cannot be an exact filter on one of them. + AllowedFilter::callback( + 'usable', + fn ($query, $value) => filter_var($value, FILTER_VALIDATE_BOOLEAN) + ? $query->usable() + : $query->whereNot(fn ($query) => $query->usable()), + ), + ]) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($keys, AnchorEnrollmentKeyData::class); + } + + public function store(StoreAnchorEnrollmentKeyRequest $request) + { + $issued = $this->keys->issue( + name: $request->string('name')->toString(), + mode: $request->mode(), + maxUses: $request->maxUses(), + expiresInMinutes: $request->expiresInMinutes(), + actor: $request->user(), + ); + + // The terms of the key are exactly what makes it dangerous, so they are + // recorded in full. The token itself never is. + Audit::record( + AuditEvent::ADMIN_ANCHOR_ENROLLMENT_KEY_CREATED, + subject: $issued->key, + properties: [ + 'name' => $issued->key->name, + 'mode' => $issued->key->mode?->value, + 'max_uses' => $issued->key->max_uses, + 'expires_at' => $issued->key->expires_at?->toIso8601String(), + ], + ); + + return AnchorEnrollmentKeyData::fromModel($issued->key, $issued->token); + } + + /** + * Withdraw a key without erasing it. + * + * Revoking is the remediation, so it must leave behind the record of what + * was admitted while the key was live. Erasure is a separate, narrower + * action -- see {@see destroy()}. + */ + public function revoke(AnchorEnrollmentKey $enrollmentKey) + { + if ($enrollmentKey->revoked_at === null) { + $enrollmentKey->update(['revoked_at' => now()]); + } + + Audit::record( + AuditEvent::ADMIN_ANCHOR_ENROLLMENT_KEY_REVOKED, + subject: $enrollmentKey, + properties: ['name' => $enrollmentKey->name, 'uses' => $enrollmentKey->uses], + ); + + return AnchorEnrollmentKeyData::fromModel($enrollmentKey->loadMissing('createdBy')); + } + + /** + * Housekeeping for a key that can no longer admit anything. + * + * Deliberately refuses an active key: allowing it would make deletion a + * quieter synonym for revocation, and the quieter path is the one that gets + * taken when someone would rather the incident left no roster entry. + */ + public function destroy(AnchorEnrollmentKey $enrollmentKey) + { + if ($enrollmentKey->status() === EnrollmentKeyStatus::ACTIVE) { + throw new BadRequestHttpException('Revoke this enrollment key before deleting it.'); + } + + $properties = ['name' => $enrollmentKey->name, 'uses' => $enrollmentKey->uses]; + + $enrollmentKey->delete(); + + Audit::record( + AuditEvent::ADMIN_ANCHOR_ENROLLMENT_KEY_DELETED, + subject: $enrollmentKey, + properties: $properties, + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/AuditLogController.php b/app/Http/Controllers/Admin/AuditLogController.php new file mode 100644 index 00000000000..608d0272c2f --- /dev/null +++ b/app/Http/Controllers/Admin/AuditLogController.php @@ -0,0 +1,45 @@ +with(['actor', 'subject']) + ->allowedFilters([ + 'event', + 'batch', + AllowedFilter::exact('actor_id'), + AllowedFilter::exact('subject_id'), + AllowedFilter::exact('subject_type'), + // Prefix match on the dotted event key, so "filter[area]=admin.node" pulls back + // every node event without the caller naming each one. + AllowedFilter::callback('area', fn ($query, $value) => $query->where( + // Wildcards stripped from the input so a caller cannot turn the prefix match + // into an arbitrary LIKE pattern. + 'event', 'like', str_replace(['%', '_'], '', (string) $value).'%', + )), + AllowedFilter::callback('since', fn ($query, $value) => $query->where('created_at', '>=', $value)), + AllowedFilter::callback('until', fn ($query, $value) => $query->where('created_at', '<=', $value)), + ]) + ->defaultSort('-created_at') + ->allowedSorts(['created_at']) + ->paginate(min($request->integer('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($logs, AuditLogData::class); + } +} diff --git a/app/Http/Controllers/Admin/ClusterController.php b/app/Http/Controllers/Admin/ClusterController.php new file mode 100644 index 00000000000..24605c1f4a0 --- /dev/null +++ b/app/Http/Controllers/Admin/ClusterController.php @@ -0,0 +1,31 @@ +forceFill(['flagged_at' => null, 'flag_reason' => null])->save(); + + Audit::record( + AuditEvent::ADMIN_CLUSTER_UNFLAGGED, + subject: $cluster, + properties: ['name' => $cluster->name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/CotermController.php b/app/Http/Controllers/Admin/CotermController.php deleted file mode 100644 index 8200e312362..00000000000 --- a/app/Http/Controllers/Admin/CotermController.php +++ /dev/null @@ -1,131 +0,0 @@ -withCount(['nodes']) - ->defaultSort('-id') - ->allowedFilters( - ['name', AllowedFilter::custom( - '*', new FiltersCotermWildcard(), - )], - ) - ->paginate(min($request->query('per_page', 50), 100))->appends( - $request->query(), - ); - - return fractal($addressPools, new CotermTransformer())->respond(); - } - - public function show(Coterm $coterm) - { - $coterm->loadCount(['nodes']); - - return fractal($coterm, new CotermTransformer())->respond(); - } - - public function store(StoreCotermRequest $request) - { - $creds = $this->cotermTokenCreator->handle(); - $coterm = Coterm::create([ - ...$request->safe()->except('node_ids'), - ...$creds, - ]); - if ($request->node_ids !== null) { - Node::whereIn('id', $request->node_ids)->whereNull('coterm_id')->update( - ['coterm_id' => $coterm->id], - ); - } - $coterm->loadCount(['nodes']); - - return fractal($coterm, new CotermTransformer(includeToken: true))->respond(); - } - - public function update(UpdateCotermRequest $request, Coterm $coterm) - { - $coterm->update($request->validated()); - if ($request->node_ids !== null) { - Node::whereIn('id', $request->node_ids)->whereNull('coterm_id')->update( - ['coterm_id' => $coterm->id], - ); - Node::where('coterm_id', $coterm->id)->whereNotIn('id', $request->node_ids)->update( - ['coterm_id' => null], - ); - } - $coterm->loadCount(['nodes']); - - return fractal($coterm, new CotermTransformer())->respond(); - } - - public function getAttachedNodes(Request $request, Coterm $coterm) - { - $nodes = QueryBuilder::for($coterm->nodes()) - ->withCount('servers') - ->allowedFilters( - ['name', 'fqdn', AllowedFilter::exact( - 'location_id', - ), AllowedFilter::custom('*', new FiltersNodeWildcard())], - ) - ->paginate(min($request->query('per_page', 50), 100))->appends( - $request->query(), - ); - - return fractal($nodes, new NodeTransformer())->respond(); - } - - public function updateAttachedNodes(UpdateAttachedNodesRequest $request, Coterm $coterm) - { - Node::whereIn('id', $request->node_ids)->whereNull('coterm_id')->update( - ['coterm_id' => $coterm->id], - ); - Node::where('coterm_id', $coterm->id)->whereNotIn('id', $request->node_ids)->update( - ['coterm_id' => null], - ); - $coterm->loadCount(['nodes']); - - return fractal($coterm, new CotermTransformer())->respond(); - } - - public function resetCotermToken(Coterm $coterm) - { - $creds = $this->cotermTokenCreator->handle(); - $coterm->update([ - 'token_id' => $creds['token_id'], - 'token' => $creds['token'], - ]); - - return fractal($coterm, new CotermTransformer(includeToken: true))->parseIncludes('token') - ->respond(); - } - - public function destroy(DeleteCotermRequest $request, Coterm $coterm) - { - $coterm->delete(); - - return $this->returnNoContent(); - } -} diff --git a/app/Http/Controllers/Admin/ISOs/ISOController.php b/app/Http/Controllers/Admin/ISOs/ISOController.php new file mode 100644 index 00000000000..4db8044ef10 --- /dev/null +++ b/app/Http/Controllers/Admin/ISOs/ISOController.php @@ -0,0 +1,116 @@ +allowedFilters(['name']) + ->defaultSort('name') + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($isos, ISOEloquentData::class); + } + + public function store(StoreISORequest $request) + { + $iso = $this->isos->create($request->validated()); + + Audit::record( + AuditEvent::ADMIN_ISO_CREATED, + subject: $iso, + properties: [ + 'name' => $iso->name, + 'file_name' => $iso->file_name, + 'hosted' => $iso->isHosted(), + ], + ); + + return ISOEloquentData::from($iso); + } + + public function show(ISO $iso) + { + return ISOEloquentData::from($iso); + } + + public function update(UpdateISORequest $request, ISO $iso) + { + $iso->update($request->validated()); + + Audit::record( + AuditEvent::ADMIN_ISO_UPDATED, + subject: $iso, + properties: ['name' => $iso->name, 'changed' => array_keys($iso->getChanges())], + ); + + return ISOEloquentData::from($iso); + } + + /** + * What a URL points at, so the add form can fill in its own blanks. + * + * Proxmox is the one that can answer this -- it is a node-side probe -- so + * any node capable of holding ISOs will do. The library is panel-wide, so + * which node answered has no bearing on the record that results. + */ + public function queryLink(Request $request) + { + $request->validate(['link' => ['required', 'url']]); + + $node = Node::query() + ->whereHas('storages', fn ($storages) => $storages->stores(StorageContentType::ISO)) + ->first() ?? throw new ConflictHttpException( + 'No node has ISO storage, so Convoy cannot inspect that link.', + ); + + return FileMetaData::from( + $this->client->setNode($node)->getFileMetadata($request->string('link')->toString()), + ); + } + + public function destroy(ISO $iso) + { + $name = $iso->name; + + $this->isos->delete($iso); + + Audit::record( + AuditEvent::ADMIN_ISO_DELETED, + subject: $iso, + properties: ['name' => $name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/ISOs/ISOUploadController.php b/app/Http/Controllers/Admin/ISOs/ISOUploadController.php new file mode 100644 index 00000000000..a5920cc5e63 --- /dev/null +++ b/app/Http/Controllers/Admin/ISOs/ISOUploadController.php @@ -0,0 +1,57 @@ +validate([ + 'file' => ['required', 'file', 'mimes:iso'], + ]); + + $upload = $request->file('file'); + $sha256 = $this->inspector->sha256OfFile($upload->getRealPath()); + $path = "iso-{$sha256}.iso"; + + $disk = Filesystem::disk($this->resolver->diskName()); + + if (! $disk->exists($path)) { + $disk->putFileAs('', $upload, $path); + } + + Audit::record( + AuditEvent::ADMIN_ISO_UPLOADED, + properties: ['sha256' => $sha256, 'size' => $disk->size($path)], + ); + + return [ + 'path' => $path, + 'sha256' => $sha256, + 'size' => $disk->size($path), + // What it will be called on a node, defaulted from what the + // operator uploaded so the name in Proxmox stays recognisable. + 'file_name' => Str::of($upload->getClientOriginalName())->basename()->toString(), + ]; + } +} diff --git a/app/Http/Controllers/Admin/Images/ImageDefinitionController.php b/app/Http/Controllers/Admin/Images/ImageDefinitionController.php new file mode 100644 index 00000000000..b56885989d5 --- /dev/null +++ b/app/Http/Controllers/Admin/Images/ImageDefinitionController.php @@ -0,0 +1,81 @@ +definitions()) + ->allowedFilters(['name', AllowedFilter::exact('is_admin_only')]) + ->allowedIncludes(['versions']) + ->defaultSort('name') + ->with('versions') + ->get(); + + return ImageDefinitionData::collect($definitions, DataCollection::class); + } + + public function store(ImageDefinitionRequest $request, ImageGroup $imageGroup) + { + $definition = $imageGroup->definitions()->create($request->validated()); + + Audit::record( + AuditEvent::ADMIN_IMAGE_CREATED, + subject: $definition, + properties: ['name' => $definition->name, 'group' => $imageGroup->name], + ); + + return ImageDefinitionData::from($definition); + } + + public function show(ImageGroup $imageGroup, ImageDefinition $imageDefinition) + { + return ImageDefinitionData::from($imageDefinition->load('versions'))->include('versions'); + } + + public function update( + ImageDefinitionRequest $request, + ImageGroup $imageGroup, + ImageDefinition $imageDefinition, + ) { + $imageDefinition->update($request->validated()); + + Audit::record( + AuditEvent::ADMIN_IMAGE_UPDATED, + subject: $imageDefinition, + properties: [ + 'name' => $imageDefinition->name, + 'changed' => array_keys($imageDefinition->getChanges()), + ], + ); + + return ImageDefinitionData::from($imageDefinition); + } + + public function destroy(ImageGroup $imageGroup, ImageDefinition $imageDefinition): Response + { + $name = $imageDefinition->name; + + $imageDefinition->delete(); + + Audit::record( + AuditEvent::ADMIN_IMAGE_DELETED, + subject: $imageDefinition, + properties: ['name' => $name, 'group' => $imageGroup->name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/Images/ImageGroupController.php b/app/Http/Controllers/Admin/Images/ImageGroupController.php new file mode 100644 index 00000000000..2d11eeddff0 --- /dev/null +++ b/app/Http/Controllers/Admin/Images/ImageGroupController.php @@ -0,0 +1,73 @@ +allowedFilters(['name', AllowedFilter::exact('is_admin_only')]) + ->allowedIncludes(['definitions']) + ->defaultSort('name') + ->get(); + + return ImageGroupData::collect($groups, DataCollection::class); + } + + public function store(ImageGroupRequest $request) + { + $group = ImageGroup::create($request->validated()); + + Audit::record( + AuditEvent::ADMIN_IMAGE_GROUP_CREATED, + subject: $group, + properties: ['name' => $group->name], + ); + + return ImageGroupData::from($group); + } + + public function show(ImageGroup $imageGroup) + { + return ImageGroupData::from($imageGroup->load('definitions.versions'))->include('definitions'); + } + + public function update(ImageGroupRequest $request, ImageGroup $imageGroup) + { + $imageGroup->update($request->validated()); + + Audit::record( + AuditEvent::ADMIN_IMAGE_GROUP_UPDATED, + subject: $imageGroup, + properties: ['name' => $imageGroup->name, 'changed' => array_keys($imageGroup->getChanges())], + ); + + return ImageGroupData::from($imageGroup); + } + + public function destroy(ImageGroup $imageGroup): Response + { + $name = $imageGroup->name; + + $imageGroup->delete(); + + Audit::record( + AuditEvent::ADMIN_IMAGE_GROUP_DELETED, + subject: $imageGroup, + properties: ['name' => $name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/Images/ImageSchemaController.php b/app/Http/Controllers/Admin/Images/ImageSchemaController.php new file mode 100644 index 00000000000..78c4827d368 --- /dev/null +++ b/app/Http/Controllers/Admin/Images/ImageSchemaController.php @@ -0,0 +1,40 @@ +query('node_id')) + ? Node::find($nodeId) + : null; + + return [ + // Whose rules these are, so the UI can say so rather than implying + // every node agrees. + 'node_id' => $node?->id, + 'parameters' => $schemas->forNode($node), + // The panel's own keys. They name slots rather than carrying + // Proxmox values, so the form has to render them itself. + 'meta_keys' => OsProfiles::META_KEYS, + 'defaults' => collect(['l26', 'win11']) + ->mapWithKeys(fn (string $ostype) => [$ostype => OsProfiles::defaults($ostype)]) + ->all(), + ]; + } +} diff --git a/app/Http/Controllers/Admin/Images/ImageUploadController.php b/app/Http/Controllers/Admin/Images/ImageUploadController.php new file mode 100644 index 00000000000..8e4cfc888db --- /dev/null +++ b/app/Http/Controllers/Admin/Images/ImageUploadController.php @@ -0,0 +1,74 @@ +validate([ + 'file' => ['required', 'file'], + ]); + + $upload = $request->file('file'); + $extension = strtolower((string) $upload->getClientOriginalExtension()); + + if (! in_array($extension, ['qcow2', 'img', 'raw'], true)) { + throw new UnprocessableEntityHttpException( + 'A disk image must be a .qcow2, .img or .raw file.', + ); + } + + $sha256 = $this->inspector->sha256OfFile($upload->getRealPath()); + + // Named after the hash, like the copy that lands on a node: uploading + // the same image twice costs one file, and a re-upload after a failed + // version cannot leave an orphan under a different name. + $format = $extension === 'qcow2' ? 'qcow2' : 'raw'; + $path = "image-{$sha256}.{$format}"; + + $disk = Filesystem::disk($this->resolver->diskName()); + + if (! $disk->exists($path)) { + $disk->putFileAs('', $upload, $path); + } + + $virtualSize = $this->inspector->virtualSizeOfFile($disk->path($path)) + // A raw image is its own virtual size; only qcow2 declares one. + ?? $disk->size($path); + + Audit::record( + AuditEvent::ADMIN_IMAGE_UPLOADED, + properties: ['sha256' => $sha256, 'size' => $disk->size($path)], + ); + + return [ + 'path' => $path, + 'sha256' => $sha256, + 'size' => $disk->size($path), + 'virtual_size' => $virtualSize, + 'format' => $format, + ]; + } +} diff --git a/app/Http/Controllers/Admin/Images/ImageVersionController.php b/app/Http/Controllers/Admin/Images/ImageVersionController.php new file mode 100644 index 00000000000..7385a7085bb --- /dev/null +++ b/app/Http/Controllers/Admin/Images/ImageVersionController.php @@ -0,0 +1,100 @@ +versions() + ->orderByDesc('version_major') + ->orderByDesc('version_minor') + ->orderByDesc('version_patch') + ->get(); + + return ImageVersionData::collect($versions, DataCollection::class); + } + + public function store( + ImageVersionRequest $request, + ImageGroup $imageGroup, + ImageDefinition $imageDefinition, + ) { + $version = $imageDefinition->versions()->create($request->validated()); + + Audit::record( + AuditEvent::ADMIN_IMAGE_VERSION_CREATED, + subject: $version, + properties: ['image' => $imageDefinition->name, 'version' => $version->version], + ); + + return ImageVersionData::from($version); + } + + public function show(ImageGroup $imageGroup, ImageDefinition $imageDefinition, ImageVersion $imageVersion) + { + return ImageVersionData::from($imageVersion); + } + + /** + * Only `is_active` is editable. + * + * A version's disks are what a server was built from; rewriting them would + * silently change the answer to "where did this machine come from" for + * every server already pointing here. A corrected build is a new version. + */ + public function update( + ImageVersionRequest $request, + ImageGroup $imageGroup, + ImageDefinition $imageDefinition, + ImageVersion $imageVersion, + ) { + $imageVersion->update($request->safe()->only('is_active')); + + Audit::record( + AuditEvent::ADMIN_IMAGE_VERSION_UPDATED, + subject: $imageVersion, + properties: ['version' => $imageVersion->version, 'is_active' => $imageVersion->is_active], + ); + + return ImageVersionData::from($imageVersion); + } + + public function destroy( + ImageGroup $imageGroup, + ImageDefinition $imageDefinition, + ImageVersion $imageVersion, + ): Response { + // Deployments reference the version they built from, and that record is + // the only place a server's provenance lives. Retiring hides it from + // the picker without destroying the history. + if ($imageVersion->deployments()->exists()) { + throw new ConflictHttpException( + 'Servers were built from this version. Retire it instead of deleting it.', + ); + } + + $number = $imageVersion->version; + + $imageVersion->delete(); + + Audit::record( + AuditEvent::ADMIN_IMAGE_VERSION_DELETED, + subject: $imageVersion, + properties: ['image' => $imageDefinition->name, 'version' => $number], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/LocationController.php b/app/Http/Controllers/Admin/LocationController.php index f632385705f..41ce379cc73 100644 --- a/app/Http/Controllers/Admin/LocationController.php +++ b/app/Http/Controllers/Admin/LocationController.php @@ -1,62 +1,104 @@ withCount(['nodes', 'servers']) - ->defaultSort('-id') - // @phpstan-ignore-next-line - ->allowedFilters( - ['short_code', AllowedFilter::custom('*', new FiltersLocationWildcard())], + ->withCount(['nodes', 'servers']) + ->defaultSort('short_code') + ->allowedFilters( + ['short_code', AllowedFilter::custom('*', new FiltersLocationWildcard)], ) - ->paginate(min($request->query('per_page', 50), 100))->appends( + ->paginate(min($request->query('per_page', 50), 100))->appends( $request->query(), ); - return fractal($locations, new LocationTransformer())->respond(); + return PaginationMeta::paginate($locations, LocationData::class); + } + + public function show(Location $location) + { + $location->loadCount('nodes', 'servers'); + + return LocationData::from($location); + } + + public function showAttachedNodes(Location $location) + { + $nodes = $location->nodes() + ->withCount('servers') + ->orderBy('name') + ->get(); + + return NodeData::collect($nodes, DataCollection::class); } public function store(LocationFormRequest $request) { $location = Location::create($request->validated()); + $location->loadCount('nodes', 'servers'); + + Audit::record( + AuditEvent::ADMIN_LOCATION_CREATED, + subject: $location, + properties: ['short_code' => $location->short_code], + ); - return fractal($location, new LocationTransformer())->respond(); + return LocationData::from($location); } public function update(LocationFormRequest $request, Location $location) { $location->update($request->validated()); - return fractal($location, new LocationTransformer())->respond(); + Audit::record( + AuditEvent::ADMIN_LOCATION_UPDATED, + subject: $location, + properties: ['short_code' => $location->short_code, 'changed' => array_keys($location->getChanges())], + ); + + $location->loadCount('nodes', 'servers'); + + return LocationData::from($location); } public function destroy(Location $location) { $location->loadCount('nodes'); - // @phpstan-ignore-next-line if ($location->nodes_count > 0) { throw new BadRequestHttpException( 'The location cannot be deleted with nodes still associated.', ); } + $shortCode = $location->short_code; + $location->delete(); - return $this->returnNoContent(); + Audit::record( + AuditEvent::ADMIN_LOCATION_DELETED, + subject: $location, + properties: ['short_code' => $shortCode], + ); + + return response()->noContent(); } } diff --git a/app/Http/Controllers/Admin/Nodes/AddressController.php b/app/Http/Controllers/Admin/Nodes/AddressController.php index ff633ec02b3..794fdcd60ea 100644 --- a/app/Http/Controllers/Admin/Nodes/AddressController.php +++ b/app/Http/Controllers/Admin/Nodes/AddressController.php @@ -1,35 +1,31 @@ addresses()) - ->with('server') - ->defaultSort('-id') - ->allowedFilters( - ['address', AllowedFilter::exact( - 'type', - ), AllowedFilter::custom( - '*', - new FiltersAddressWildcard(), - ), AllowedFilter::exact('server_id')->nullable()], - ) - ->paginate(min($request->query('per_page', 50), 999999))->appends( + ->with('server') + ->defaultSort('-addresses.id') + ->allowedFilters( + ['address', AllowedFilter::exact('type'), + AllowedFilter::custom('*', new FiltersAddressWildcard), + AllowedFilter::exact('server_id')->nullable()], + ) + ->paginate(min($request->query('per_page', 50), 100))->appends( $request->query(), ); - return fractal($addresses, new AddressTransformer())->parseIncludes($request->include) - ->respond(); + return PaginationMeta::paginate($addresses, IpamAddressData::class); } } diff --git a/app/Http/Controllers/Admin/Nodes/IsoController.php b/app/Http/Controllers/Admin/Nodes/IsoController.php deleted file mode 100644 index a34ba343d0b..00000000000 --- a/app/Http/Controllers/Admin/Nodes/IsoController.php +++ /dev/null @@ -1,96 +0,0 @@ -where('iso_library.node_id', $node->id) - ->allowedFilters(['name']) - ->paginate(min($request->query('per_page', 50), 100))->appends( - $request->query(), - ); - - return fractal($isos, new IsoTransformer())->respond(); - } - - public function store(StoreIsoRequest $request, Node $node) - { - $shouldDownload = $request->boolean('should_download'); - - if ($shouldDownload) { - $checksumData = (bool)$request->checksum_algorithum ? ChecksumData::from([ - 'algorithm' => ChecksumAlgorithm::from($request->checksum_algorithum), - 'checksum' => $request->checksum, - ]) : null; - - $iso = $this->isoService->download( - $node, $request->name, $request->file_name, $request->link, $checksumData, - $request->hidden, - ); - } else { - $isoFromProxmox = $this->isoService->getIso($node, $request->file_name); - - $iso = $node->isos()->create([ - 'is_successful' => true, - 'name' => $request->name, - 'file_name' => $request->file_name, - 'size' => $isoFromProxmox->size, - 'hidden' => $request->boolean('hidden'), - 'completed_at' => now(), - ]); - } - - return fractal($iso, new IsoTransformer())->respond(); - } - - public function update(UpdateIsoRequest $request, Node $node, ISO $iso) - { - $iso->update($request->validated()); - - return fractal($iso, new IsoTransformer())->respond(); - } - - public function destroy(Node $node, ISO $iso) - { - $this->isoService->delete($node, $iso); - - return $this->returnNoContent(); - } - - public function queryLink(Request $request, Node $node) - { - Validator::make([ - 'link' => $request->link, - ], [ - 'link' => ['required', 'url'], - ])->validate(); - - $metadata = $this->repository->setNode($node)->getFileMetadata($request->link); - - return fractal($metadata, new FileMetadataTransformer())->respond(); - } -} diff --git a/app/Http/Controllers/Admin/Nodes/NetworkInterfaceController.php b/app/Http/Controllers/Admin/Nodes/NetworkInterfaceController.php new file mode 100644 index 00000000000..e63943b2197 --- /dev/null +++ b/app/Http/Controllers/Admin/Nodes/NetworkInterfaceController.php @@ -0,0 +1,139 @@ +networkInterfaces() + ->withCount(['servers', 'addressBlockGroups']) + ->with('vlans') + ->get(); + + return NetworkInterfaceData::collect( + $this->withVlanUsage($interfaces), + DataCollection::class, + ); + } + + /** + * Resolve VLAN usage for the whole list in one query. Without this each + * interface would ask for its own counts while the data object is being + * built — the list is short, but the query count would track it. + * + * @param Collection $interfaces + * @return Collection + */ + private function withVlanUsage(Collection $interfaces): Collection + { + $usage = NetworkInterface::vlanUsageFor($interfaces); + + return $interfaces->each(function (NetworkInterface $interface) use ($usage) { + $interface->resolvedVlanUsage = $usage->get($interface->id) ?? collect(); + }); + } + + public function store(NetworkInterfaceRequest $request, Node $node) + { + $data = $request->validated(); + if (($data['is_vlan_aware'] ?? false) === false) { + $data['vlan_tag'] = null; + } + + $interface = $node->networkInterfaces()->create($data); + + Audit::record( + AuditEvent::ADMIN_NODE_INTERFACE_CREATED, + subject: $node, + properties: ['name' => $interface->name, 'is_vlan_aware' => $interface->is_vlan_aware], + ); + + return $this->respondWith($interface); + } + + public function update(NetworkInterfaceRequest $request, Node $node, NetworkInterface $networkInterface) + { + $data = $request->validated(); + if (($data['is_vlan_aware'] ?? $networkInterface->is_vlan_aware) === false) { + $data['vlan_tag'] = null; + } + + $networkInterface->update($data); + + if ($networkInterface->wasChanged(['name', 'is_vlan_aware', 'vlan_tag'])) { + if (! $networkInterface->is_vlan_aware) { + Server::query() + ->where('network_interface_id', $networkInterface->id) + ->update(['vlan_tag' => null]); + + // A VLAN on a bridge that no longer trunks is unreachable: the + // sync forces a null tag on every server here, so nothing can + // resolve to it. Drop the declarations alongside the server + // tags this already clears, rather than leave a tree of VLANs + // that can never have a member. + $networkInterface->vlans()->delete(); + } + + Server::query() + ->where('network_interface_id', $networkInterface->id) + ->each(fn (Server $server) => dispatch(new SyncNetworkSettingsJob($server))); + } + + Audit::record( + AuditEvent::ADMIN_NODE_INTERFACE_UPDATED, + subject: $node, + properties: [ + 'name' => $networkInterface->name, + 'changed' => array_keys($networkInterface->getChanges()), + ], + ); + + return $this->respondWith($networkInterface); + } + + /** + * The client merges a write response straight into its cached list, so + * every write path has to carry the same derived fields the list does — + * otherwise editing an interface would blank the servers, pools and VLANs + * already on it until the next refetch. + */ + private function respondWith(NetworkInterface $interface): NetworkInterfaceData + { + $interface->resolvedVlanUsage = null; + + return NetworkInterfaceData::from( + $interface + ->loadCount(['servers', 'addressBlockGroups']) + ->load('vlans'), + ); + } + + public function destroy(DeleteNetworkInterfaceRequest $request, Node $node, NetworkInterface $networkInterface): Response + { + $name = $networkInterface->name; + + $networkInterface->delete(); + + Audit::record( + AuditEvent::ADMIN_NODE_INTERFACE_DELETED, + subject: $node, + properties: ['name' => $name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/Nodes/NodeConnectionTestController.php b/app/Http/Controllers/Admin/Nodes/NodeConnectionTestController.php new file mode 100644 index 00000000000..0b6fd3b89a2 --- /dev/null +++ b/app/Http/Controllers/Admin/Nodes/NodeConnectionTestController.php @@ -0,0 +1,31 @@ +replicate() ?? new Node; + $attributes = $request->validated(); + + // Saved-node forms deliberately leave credentials blank to mean + // "keep the existing value". Test an unsaved copy with the edited + // connection fields while retaining those stored credentials. + foreach (['token_id', 'token_secret'] as $credential) { + if (! filled($attributes[$credential] ?? null)) { + unset($attributes[$credential]); + } + } + + $node->fill($attributes); + + return $this->service->handle($node); + } +} diff --git a/app/Http/Controllers/Admin/Nodes/NodeController.php b/app/Http/Controllers/Admin/Nodes/NodeController.php index 7b3ade1e4fd..5a6b4465b71 100644 --- a/app/Http/Controllers/Admin/Nodes/NodeController.php +++ b/app/Http/Controllers/Admin/Nodes/NodeController.php @@ -1,62 +1,92 @@ withCount(['servers']) - ->allowedFilters( - [AllowedFilter::exact('id'), 'name', 'fqdn', AllowedFilter::exact( - 'location_id', - ), AllowedFilter::exact( - 'coterm_id', - )->nullable(), AllowedFilter::custom( - '*', - new FiltersNodeWildcard(), - )], - ) - ->paginate(min($request->query('per_page', 50), 100))->appends( + $nodes = QueryBuilder::for(Node::query()->with('cluster')) + ->withCount(['servers']) + ->allowedFilters([ + AllowedFilter::custom('*', new FiltersNodeWildcard), + AllowedFilter::exact('id'), + 'display_name', + 'fqdn', + AllowedFilter::exact('location_id'), + AllowedFilter::exact('relay_id')->nullable(), + // Nodes with no agent installed -- the v4 shape, and the thing + // the nodes list nudges an operator to finish. + AllowedFilter::callback( + 'unlinked', + fn ($query, $value) => filter_var($value, FILTER_VALIDATE_BOOLEAN) + ? $query->whereNull('agent_uuid') + : $query->whereNotNull('agent_uuid'), + ), + ]) + ->paginate(min($request->query('per_page', 50), 100))->appends( $request->query(), ); - return fractal($nodes, new NodeTransformer())->respond(); + return PaginationMeta::paginate($nodes, NodeData::class); } public function show(Node $node) { - $node->append(['memory_allocated', 'disk_allocated']); - - $node->loadCount('servers'); + $node->append(['memory_allocated']) + ->loadCount('servers'); - return fractal($node, new NodeTransformer())->respond(); + return NodeData::from($node); } - public function store(StoreNodeRequest $request) + public function update(UpdateNodeRequest $request, Node $node) { - $node = Node::create($request->validated()); + $node->update($request->validated()); + + // Credentials for the node live in these columns; record which fields moved, never + // their values. + Audit::record( + AuditEvent::ADMIN_NODE_UPDATED, + subject: $node, + properties: ['name' => $node->name, 'changed' => array_keys($node->getChanges())], + ); - return fractal($node, new NodeTransformer())->respond(); + $node->append(['memory_allocated']) + ->loadCount('servers'); + + return NodeData::from($node); } - public function update(UpdateNodeRequest $request, Node $node) + /** + * A fresh install command for the agent on this host. + * + * Serves both jobs: installing an agent on a node that has never had one + * (a node carried over from v4), and re-keying one that has. + */ + public function agentEnrollment(Node $node, AnchorEnrollmentService $enrollment) { - $node->update($request->validated()); + $details = $enrollment->issue($node); - return fractal($node, new NodeTransformer())->respond(); + Audit::record( + AuditEvent::ADMIN_ANCHOR_ENROLLMENT_ROTATED, + subject: $node, + properties: ['name' => $node->display_name], + ); + + return $details; } public function destroy(Node $node) @@ -69,8 +99,12 @@ public function destroy(Node $node) ); } + $properties = ['name' => $node->name, 'fqdn' => $node->fqdn]; + $node->delete(); - return $this->returnNoContent(); + Audit::record(AuditEvent::ADMIN_NODE_DELETED, subject: $node, properties: $properties); + + return response()->noContent(); } } diff --git a/app/Http/Controllers/Admin/Nodes/NodeStatusController.php b/app/Http/Controllers/Admin/Nodes/NodeStatusController.php new file mode 100644 index 00000000000..330efbcd525 --- /dev/null +++ b/app/Http/Controllers/Admin/Nodes/NodeStatusController.php @@ -0,0 +1,35 @@ +setNode($node)->getStatus(); + } catch (ConvoyRequestException|GuzzleRequestException|ConnectionException $e) { + // Letting this escape produced an anonymous 500, so the overview could + // only say "live status is unavailable" -- true, useless, and the same + // sentence whether the certificate was untrusted or the token was + // wrong. Classify it the way the connection test already does and the + // UI can name the cause and the fix. + throw new NodeUnreachableException( + ConnectionErrorCode::classify($e->getMessage()), + previous: $e, + ); + } + } +} diff --git a/app/Http/Controllers/Admin/Nodes/StorageController.php b/app/Http/Controllers/Admin/Nodes/StorageController.php new file mode 100644 index 00000000000..1db730bd074 --- /dev/null +++ b/app/Http/Controllers/Admin/Nodes/StorageController.php @@ -0,0 +1,226 @@ +mapWithLiveData( + $node, + $node->storages()->withUsageSums()->orderBy('id', 'desc')->get(), + ); + } + + /** + * @throws RequestException + */ + public function fetchFromProxmox(Node $node) + { + return StorageData::collect( + $this->client->setNode($node)->getStorages(), + DataCollection::class, + ); + } + + /** + * @throws Throwable + */ + public function store(StorageRequest $request, Node $node) + { + // What the storage may hold comes from the node, not the request. The + // form used to submit six tick boxes for it; PVE already publishes the + // answer, and the poll keeps it current from here on. + $reported = $this->liveStorage->get($node, $request->string('name')->toString()); + + // A definition is filed once per scope, so the node's scope has to be + // known. It normally is (registration polls the node immediately); + // when it is not, resolve on the spot rather than filing the row + // somewhere it would have to be migrated out of. + $cluster = $node->cluster ?? $this->clusterIdentity->resolve($node); + + abort_if( + $cluster === null, + 422, + 'Convoy could not reach this node to determine which cluster it is in. Check connectivity and try again.', + ); + + $storage = $this->connection->transaction(function () use ($request, $node, $reported, $cluster) { + // Attach-or-create: registering `ceph-vm` through a second node is + // a statement about that node, not a second pool. The scope's + // unique (cluster_id, name) makes creating a duplicate impossible + // even if two registrations race. + $storage = Storage::query()->firstOrCreate( + [ + 'cluster_id' => $cluster->id, + 'name' => $request->string('name')->toString(), + ], + [ + ...$request->validated(), + // PVE's content list, verbatim. What the storage can hold + // is read off it, so there is one place for the answer to + // live and no way for a projection of it to drift. + 'pve_content' => $reported?->content, + ], + ); + + StorageToNode::query()->firstOrCreate([ + 'storage_id' => $storage->id, + 'node_id' => $node->id, + ]); + + return $storage; + }); + + Audit::record( + AuditEvent::ADMIN_NODE_STORAGE_CREATED, + subject: $node, + properties: ['name' => $storage->name, 'stores_backups' => $storage->stores_backups], + ); + + return StorageEloquentData::fromModel( + $node->storages()->withUsageSums()->find($storage->id) ?? $storage, + $this->liveStorage->get($node, $storage->name), + $node, + ); + } + + /** + * @throws Throwable + */ + public function update(StorageRequest $request, Node $node, Storage $storage) + { + $this->connection->transaction(function () use ($request, $node, $storage) { + $storage->update($request->validated()); + + // Nothing here assigns a backup order any more. It used to be + // granted when the operator first ticked "stores backups", but that + // box is gone -- content comes from Proxmox now -- and the pivot + // sorts on creation, so a backup-capable storage already has one by + // the time it can be edited. + + Audit::record( + AuditEvent::ADMIN_NODE_STORAGE_UPDATED, + subject: $node, + properties: ['name' => $storage->name, 'changed' => array_keys($storage->getChanges())], + ); + }); + + return StorageEloquentData::fromModel( + $storage, + $this->liveStorage->get($node, $storage->name), + ); + } + + public function updateBackupOrder(UpdateBackupOrderRequest $request, Node $node) + { + /* + * Written per node rather than through `setNewOrder()`, which matches on + * `storage_id` alone: a storage mounted by several nodes would have its + * order rewritten on all of them by a drag performed on one. Backup + * order is a property of "this node's preference", not of the storage. + */ + $this->connection->transaction(function () use ($request, $node) { + foreach ($request->array('ids') as $position => $storageId) { + StorageToNode::query() + ->where('storage_id', $storageId) + ->where('node_id', $node->id) + ->update(['backup_order' => $position + 1]); + } + + Audit::record( + AuditEvent::ADMIN_NODE_STORAGE_BACKUP_ORDER_UPDATED, + subject: $node, + properties: ['order' => $request->array('ids')], + ); + }); + + return $this->mapWithLiveData( + $node, + $node->storages()->withUsageSums()->orderBy('id', 'desc')->get(), + ); + } + + public function destroy(Node $node, Storage $storage) + { + abort_unless( + $node->storages()->whereKey($storage->getKey())->exists(), + 404, + ); + + /* + * Detach rather than delete when other nodes still reach this storage. + * Removing it from one node's list is not a statement about the pool + * itself, and deleting the row would silently take it off every other + * node that was using it. + */ + $detachedOnly = $storage->nodes()->count() > 1; + + if ($detachedOnly) { + $storage->nodes()->detach($node->id); + } else { + $storage->delete(); + } + + // Two materially different outcomes behind one endpoint: detaching leaves the pool intact + // for other nodes, deleting does not. The log has to say which happened. + Audit::record( + AuditEvent::ADMIN_NODE_STORAGE_DELETED, + subject: $node, + properties: ['name' => $storage->name, 'detached_only' => $detachedOnly], + ); + + return response()->noContent(); + } + + /** + * Merge the live Proxmox status (capacity/usage — the source of truth) into + * each Convoy storage record. Degrades gracefully: a storage with no live + * match (node offline / storage missing) comes back flagged `online: false` + * with null physical figures rather than failing the whole list. + * + * @param Collection $storages + * @return DataCollection + */ + private function mapWithLiveData(Node $node, Collection $storages): DataCollection + { + $live = $this->liveStorage->forNode($node); + // Eager-loaded so naming the other nodes costs one query, not one per row. + $storages->loadMissing('nodes'); + + return StorageEloquentData::collect( + $storages->map(fn (Storage $storage) => StorageEloquentData::fromModel( + $storage, + $live->get($storage->name), + $node, + ))->all(), + DataCollection::class, + ); + } +} diff --git a/app/Http/Controllers/Admin/Nodes/TemplateController.php b/app/Http/Controllers/Admin/Nodes/TemplateController.php deleted file mode 100644 index 595fe6c586d..00000000000 --- a/app/Http/Controllers/Admin/Nodes/TemplateController.php +++ /dev/null @@ -1,64 +0,0 @@ -where('templates.template_group_id', $templateGroup->id) - ->defaultSort('order_column') - ->get(); - - return fractal($templates, new TemplateTransformer())->respond(); - } - - public function store(TemplateRequest $request, Node $node, TemplateGroup $templateGroup) - { - $template = Template::create( - array_merge($request->validated(), [ - 'node_id' => $node->id, - 'template_group_id' => $templateGroup->id, - ]), - ); - - return fractal($template, new TemplateTransformer())->respond(); - } - - public function update( - TemplateRequest $request, Node $node, TemplateGroup $templateGroup, Template $template, - ) - { - $template->update($request->validated()); - - return fractal($template, new TemplateTransformer())->respond(); - } - - public function destroy(Node $node, TemplateGroup $templateGroup, Template $template) - { - $template->delete(); - - return $this->returnNoContent(); - } - - public function updateOrder( - UpdateTemplateOrderRequest $request, Node $node, TemplateGroup $templateGroup, - ) - { - Template::setNewOrder($request->order); - - return fractal( - $templateGroup->templates()->ordered()->get(), new TemplateTransformer(), - )->respond(); - } -} diff --git a/app/Http/Controllers/Admin/Nodes/TemplateGroupController.php b/app/Http/Controllers/Admin/Nodes/TemplateGroupController.php deleted file mode 100644 index 25a78c00147..00000000000 --- a/app/Http/Controllers/Admin/Nodes/TemplateGroupController.php +++ /dev/null @@ -1,64 +0,0 @@ -where('template_groups.node_id', $node->id) - ->defaultSort('order_column') - ->with(['templates' => function ($query) { - $query->orderBy('order_column'); - }]) - ->allowedFilters(['name']) - ->get(); - - return fractal($templateGroups, new TemplateGroupTransformer())->parseIncludes(['templates'], - )->respond(); - } - - public function updateOrder(UpdateGroupOrderRequest $request, Node $node) - { - TemplateGroup::setNewOrder($request->order); - - return fractal( - $node->templateGroups()->with('templates')->ordered()->get(), - new TemplateGroupTransformer(), - )->parseIncludes(['templates'])->respond(); - } - - public function store(TemplateGroupRequest $request, Node $node) - { - $templateGroup = TemplateGroup::create( - array_merge($request->validated(), [ - 'node_id' => $node->id, - ]), - ); - - return fractal($templateGroup, new TemplateGroupTransformer())->respond(); - } - - public function update(TemplateGroupRequest $request, Node $node, TemplateGroup $templateGroup) - { - $templateGroup->update($request->validated()); - - return fractal($templateGroup, new TemplateGroupTransformer())->respond(); - } - - public function destroy(Node $node, TemplateGroup $templateGroup) - { - $templateGroup->delete(); - - return $this->returnNoContent(); - } -} diff --git a/app/Http/Controllers/Admin/Nodes/VlanController.php b/app/Http/Controllers/Admin/Nodes/VlanController.php new file mode 100644 index 00000000000..fe361e08a4f --- /dev/null +++ b/app/Http/Controllers/Admin/Nodes/VlanController.php @@ -0,0 +1,83 @@ +vlanUsage(); + + $vlans = $networkInterface->vlans() + ->orderBy('tag') + ->get() + ->each(function (Vlan $vlan) use ($usage) { + $vlan->servers_count = (int) $usage->get($vlan->tag, 0); + }); + + return VlanData::collect($vlans, DataCollection::class); + } + + public function store(VlanRequest $request, Node $node, NetworkInterface $networkInterface) + { + $vlan = $networkInterface->vlans()->create($request->validated()); + + // Declaring a VLAN doesn't move any server onto it, but the tag may + // already be in use — a server could have been carrying it before + // anyone wrote it down. + $vlan->servers_count = (int) $networkInterface->vlanUsage()->get($vlan->tag, 0); + + Audit::record( + AuditEvent::ADMIN_NODE_VLAN_CREATED, + subject: $node, + properties: ['interface' => $networkInterface->name, 'tag' => $vlan->tag], + ); + + return VlanData::from($vlan); + } + + public function update(VlanRequest $request, Node $node, NetworkInterface $networkInterface, Vlan $vlan) + { + $vlan->update($request->validated()); + + Audit::record( + AuditEvent::ADMIN_NODE_VLAN_UPDATED, + subject: $node, + properties: ['interface' => $networkInterface->name, 'tag' => $vlan->tag], + ); + + $vlan->servers_count = (int) $networkInterface->vlanUsage()->get($vlan->tag, 0); + + return VlanData::from($vlan); + } + + /** + * Deleting a declaration does not detach anything. The tag a server gets is + * still resolved from its own column, so a server on this tag keeps it and + * the VLAN reappears in the tree as undeclared — no Proxmox sync needed. + */ + public function destroy(Node $node, NetworkInterface $networkInterface, Vlan $vlan): Response + { + $tag = $vlan->tag; + + $vlan->delete(); + + Audit::record( + AuditEvent::ADMIN_NODE_VLAN_DELETED, + subject: $node, + properties: ['interface' => $networkInterface->name, 'tag' => $tag], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/OverviewController.php b/app/Http/Controllers/Admin/OverviewController.php index de74192ff76..2ac2d784fff 100644 --- a/app/Http/Controllers/Admin/OverviewController.php +++ b/app/Http/Controllers/Admin/OverviewController.php @@ -1,17 +1,14 @@ item($overviewService->metrics(), new OverviewTransformer) - ->respond(); + return $overview->metrics(); } } diff --git a/app/Http/Controllers/Admin/RelayController.php b/app/Http/Controllers/Admin/RelayController.php new file mode 100644 index 00000000000..cdda2d301cc --- /dev/null +++ b/app/Http/Controllers/Admin/RelayController.php @@ -0,0 +1,98 @@ +withCount('nodes') + ->defaultSort('name') + ->allowedFilters(['name']) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($relays, RelayData::class); + } + + public function show(Relay $relay) + { + return RelayData::from($relay->loadCount('nodes')); + } + + public function store(RelayFormRequest $request) + { + $relay = Relay::create([ + ...$request->validated(), + 'uuid' => (string) Str::uuid(), + 'secret' => Str::random(64), + ]); + + // The generated secret is never recorded -- it is a live credential. + Audit::record( + AuditEvent::ADMIN_RELAY_CREATED, + subject: $relay, + properties: ['name' => $relay->name], + ); + + return RelayData::from($relay->loadCount('nodes')); + } + + public function update(RelayFormRequest $request, Relay $relay) + { + $relay->update($request->validated()); + + Audit::record( + AuditEvent::ADMIN_RELAY_UPDATED, + subject: $relay, + properties: ['name' => $relay->name, 'changed' => array_keys($relay->getChanges())], + ); + + return RelayData::from($relay->loadCount('nodes')); + } + + public function enrollment(Relay $relay, AnchorEnrollmentService $enrollment) + { + $details = $enrollment->issue($relay); + + // Enrolling rotates the secret, so this both grants access and revokes + // the previous one. The issued secret itself is never recorded. + Audit::record( + AuditEvent::ADMIN_ANCHOR_ENROLLMENT_ROTATED, + subject: $relay, + properties: ['name' => $relay->name], + ); + + return $details; + } + + public function destroy(Relay $relay) + { + $relay->loadCount('nodes'); + + if ($relay->nodes_count > 0) { + throw new BadRequestHttpException('Move these nodes off this relay before deleting it.'); + } + + $name = $relay->name; + + $relay->delete(); + + Audit::record(AuditEvent::ADMIN_RELAY_DELETED, subject: $relay, properties: ['name' => $name]); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/ServerController.php b/app/Http/Controllers/Admin/ServerController.php index 354268d34df..ab516614fd0 100644 --- a/app/Http/Controllers/Admin/ServerController.php +++ b/app/Http/Controllers/Admin/ServerController.php @@ -1,77 +1,77 @@ with(['addresses', 'user', 'node']) - ->defaultSort('-id') - ->allowedFilters( - [ - AllowedFilter::custom( - '*', new FiltersServerWildcard(), - ), - AllowedFilter::custom( - 'address_pool_id', - new FiltersServerByAddressPoolId(), - ), - AllowedFilter::exact('node_id'), - AllowedFilter::exact('user_id'), - 'name', - ], - ) - ->paginate(min($request->query('per_page', 50), 100))->appends( + ->with(['addresses', 'user', 'node']) + ->defaultSort('-id') + ->allowedFilters( + [ + AllowedFilter::custom('*', new FiltersServerWildcard), + AllowedFilter::exact('node_id'), + AllowedFilter::exact('user_id'), + 'name', + 'hostname', + ], + ) + ->paginate(min($request->query('per_page', 50), 100))->appends( $request->query(), ); - return fractal($servers, new ServerBuildTransformer())->parseIncludes($request->include) - ->respond(); + return PaginationMeta::paginate($servers, ServerData::class); } public function show(Request $request, Server $server) { - $server->load(['addresses', 'user', 'node']); + $server->load(['node']); - return fractal($server, new ServerBuildTransformer())->parseIncludes($request->include) - ->respond(); + return ServerData::from($server); } public function store(StoreServerRequest $request) @@ -80,17 +80,22 @@ public function store(StoreServerRequest $request) $server->load(['addresses', 'user', 'node']); - return fractal($server, new ServerBuildTransformer())->parseIncludes(['user', 'node']) - ->respond(); + Audit::record( + AuditEvent::ADMIN_SERVER_CREATED, + subject: $server, + properties: ['name' => $server->name, 'node' => $server->node->name], + ); + + return ServerData::from($server); } public function update(UpdateGeneralInfoRequest $request, Server $server) { $this->connection->transaction(function () use ($request, $server) { - if ($request->hostname !== $server->hostname && !empty($request->hostname)) { + if ($request->hostname !== $server->hostname && ! empty($request->hostname)) { try { - $this->cloudinitService->updateHostname($server, $request->hostname); - } catch (ProxmoxConnectionException) { + $this->cloudinitService->setHostname($server, $request->hostname); + } catch (RequestException) { throw new ServiceUnavailableHttpException( message: "Server {$server->uuid} failed to sync hostname.", ); @@ -98,54 +103,134 @@ public function update(UpdateGeneralInfoRequest $request, Server $server) } $server->update($request->validated()); + + Audit::record( + AuditEvent::ADMIN_SERVER_UPDATED, + subject: $server, + properties: ['changed' => array_keys($server->getChanges())], + ); }); $server->load(['addresses', 'user', 'node']); - return fractal($server, new ServerBuildTransformer())->parseIncludes(['user', 'node']) - ->respond(); + return ServerData::from($server); } public function updateBuild(UpdateBuildRequest $request, Server $server) { $server->update($request->safe()->except('address_ids')); - $this->networkService->updateAddresses($server, $request->address_ids ?? []); + // Build/limit-only forms must not have to echo the server's addresses + // back merely to preserve them. Only reconcile IP assignments when a + // caller explicitly includes that part of the payload. + if ($request->has('address_ids')) { + $this->networkService->syncAddresses($server, $request->address_ids ?? []); + } try { $this->buildModificationService->handle($server); - } catch (ProxmoxConnectionException $e) { + } catch (RequestException $e) { // do nothing } + // Resource limits are what a customer is billed on, so a change here belongs in their + // server's feed as well as the admin log. + Audit::record( + AuditEvent::ADMIN_SERVER_BUILD_UPDATED, + subject: $server, + properties: ['changed' => array_keys($server->getChanges())], + ); + $server->load(['addresses', 'user', 'node']); - return fractal($server, new ServerBuildTransformer())->parseIncludes(['user', 'node']) - ->respond(); + return ServerData::from($server); } public function suspend(Server $server) { $this->suspensionService->toggle($server); - return $this->returnNoContent(); + Audit::record(AuditEvent::ADMIN_SERVER_SUSPENDED, subject: $server); + + return response()->noContent(); } public function unsuspend(Server $server) { $this->suspensionService->toggle($server, SuspensionAction::UNSUSPEND); - return $this->returnNoContent(); + Audit::record(AuditEvent::ADMIN_SERVER_UNSUSPENDED, subject: $server); + + return response()->noContent(); + } + + /** + * Clears a placement flag (see ServerPlacementService) after the operator + * has resolved it. The flag blocks network sync while it stands, so this + * is the explicit escape hatch for flags no re-home will ever clear -- + * e.g. an SMBIOS mismatch the operator has investigated and explained. + */ + public function unflag(Server $server) + { + $server->forceFill(['flagged_at' => null, 'flag_reason' => null])->save(); + + Audit::record( + AuditEvent::ADMIN_SERVER_UPDATED, + subject: $server, + properties: ['changed' => ['flagged_at']], + ); + + return response()->noContent(); + } + + public function getState(Server $server) + { + $state = $this->serverClient->setServer($server)->getState(); + $state->pendingPowerAction = $this->powerLock->resolve($server); + $state->lastPowerAction = $this->powerLock->result($server); + + return $state; + } + + public function sendPowerCommand(SendPowerCommandRequest $request, Server $server) + { + $command = $request->enum('command', PowerCommand::class); + + $this->powerCommand->handle($server, $command); + + // A separate event from the client-side one: "staff power-cycled your server" and "you + // power-cycled your server" read very differently in the owner's feed. + Audit::record( + AuditEvent::ADMIN_SERVER_POWER_SENT, + subject: $server, + properties: ['command' => $command->value], + ); + + return response()->noContent(); } public function destroy(Request $request, Server $server) { $this->connection->transaction(function () use ($server, $request) { - $server->update(['status' => Status::DELETING->value]); + $server->update(['lifecycle' => ServerLifecycle::DELETING->value]); + + $properties = [ + 'name' => $server->name, + 'uuid' => $server->uuid, + 'no_purge' => (bool) $request->input('no_purge', false), + ]; $this->deletionService->handle($server, $request->input('no_purge', false)); + + // Retained forever: "who deleted this server" is one of the questions an audit log + // exists to answer, and the subject morph will not resolve once the row is gone. + Audit::record( + AuditEvent::ADMIN_SERVER_DELETED, + subject: $server, + properties: $properties, + ); }); - return $this->returnNoContent(); + return response()->noContent(); } } diff --git a/app/Http/Controllers/Admin/ServerDiskController.php b/app/Http/Controllers/Admin/ServerDiskController.php new file mode 100644 index 00000000000..436a69d9c21 --- /dev/null +++ b/app/Http/Controllers/Admin/ServerDiskController.php @@ -0,0 +1,94 @@ +disks($server)); + } + + /** + * Add a secondary data disk. Sizes are in bytes (validated against the + * target storage's free-for-Convoy space by the request). + */ + public function store(AddServerDiskRequest $request, Server $server) + { + $disk = $this->allocationService->addDisk( + $server, + (int) $request->input('storage_id'), + (int) $request->input('size'), + ); + + Audit::record( + AuditEvent::ADMIN_SERVER_DISK_CREATED, + subject: $server, + properties: ['size' => $disk->size, 'storage_id' => $disk->storage_id], + ); + + return ServerDiskData::from($disk->load('storage')); + } + + /** + * Grow a secondary disk (shrink is rejected by the service). + */ + public function update(ResizeServerDiskRequest $request, Server $server, ServerDisk $disk) + { + $previousSize = $disk->size; + + $this->allocationService->resizeDisk($server, $disk, (int) $request->input('size')); + + Audit::record( + AuditEvent::ADMIN_SERVER_DISK_UPDATED, + subject: $server, + properties: ['from' => $previousSize, 'to' => (int) $request->input('size')], + ); + + return ServerDiskData::from($disk->refresh()->load('storage')); + } + + /** + * Remove a secondary disk and reclaim its space on Proxmox. + */ + public function destroy(Server $server, ServerDisk $disk): Response + { + $properties = ['size' => $disk->size, 'disk_index' => $disk->disk_index]; + + $this->allocationService->removeDisk($server, $disk); + + Audit::record( + AuditEvent::ADMIN_SERVER_DISK_DELETED, + subject: $server, + properties: $properties, + ); + + return response()->noContent(); + } + + /** + * @return Collection + */ + private function disks(Server $server): Collection + { + return $server->disks()->with('storage')->orderBy('disk_index')->get(); + } +} diff --git a/app/Http/Controllers/Admin/ServerPresetController.php b/app/Http/Controllers/Admin/ServerPresetController.php new file mode 100644 index 00000000000..eafc0908f97 --- /dev/null +++ b/app/Http/Controllers/Admin/ServerPresetController.php @@ -0,0 +1,71 @@ +allowedFilters(['name']) + ->defaultSort('name') + ->get(); + + return ServerPresetData::collect($presets, DataCollection::class); + } + + public function store(ServerPresetRequest $request) + { + $preset = ServerPreset::create($request->attributesForPreset()); + + Audit::record( + AuditEvent::ADMIN_SERVER_PRESET_CREATED, + subject: $preset, + properties: ['name' => $preset->name], + ); + + return ServerPresetData::from($preset); + } + + public function show(ServerPreset $serverPreset) + { + return ServerPresetData::from($serverPreset); + } + + public function update(ServerPresetRequest $request, ServerPreset $serverPreset) + { + $serverPreset->update($request->attributesForPreset()); + + Audit::record( + AuditEvent::ADMIN_SERVER_PRESET_UPDATED, + subject: $serverPreset, + properties: ['name' => $serverPreset->name, 'changed' => array_keys($serverPreset->getChanges())], + ); + + return ServerPresetData::from($serverPreset); + } + + public function destroy(ServerPreset $serverPreset): Response + { + $name = $serverPreset->name; + + $serverPreset->delete(); + + Audit::record( + AuditEvent::ADMIN_SERVER_PRESET_DELETED, + subject: $serverPreset, + properties: ['name' => $name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/Settings/AccountSettingsController.php b/app/Http/Controllers/Admin/Settings/AccountSettingsController.php new file mode 100644 index 00000000000..9499d03693b --- /dev/null +++ b/app/Http/Controllers/Admin/Settings/AccountSettingsController.php @@ -0,0 +1,60 @@ +present($resolver); + } + + public function update( + UpdateAccountSettingsRequest $request, + AccountSettings $settings, + AccountPolicyResolver $resolver, + ): AccountSettingsData { + $settings->allow_name_change = $request->boolean('allow_name_change'); + $settings->allow_email_change = $request->boolean('allow_email_change'); + $settings->allow_password_change = $request->boolean('allow_password_change'); + $settings->allow_avatar_change = $request->boolean('allow_avatar_change'); + + $settings->save(); + + // No subject: this is panel-wide configuration, not an action on a record. + Audit::record( + AuditEvent::ADMIN_SETTINGS_ACCOUNT_UPDATED, + properties: [ + 'allow_name_change' => $settings->allow_name_change, + 'allow_email_change' => $settings->allow_email_change, + 'allow_password_change' => $settings->allow_password_change, + 'allow_avatar_change' => $settings->allow_avatar_change, + ], + ); + + return $this->present($resolver); + } + + /** + * Read back through the resolver so this screen and the enforcement path + * can never disagree about what the stored policy means. + */ + private function present(AccountPolicyResolver $resolver): AccountSettingsData + { + $policy = $resolver->global(); + + return new AccountSettingsData( + allowNameChange: $policy->canChangeName, + allowEmailChange: $policy->canChangeEmail, + allowPasswordChange: $policy->canChangePassword, + allowAvatarChange: $policy->canChangeAvatar, + ); + } +} diff --git a/app/Http/Controllers/Admin/Settings/AnchorSettingsController.php b/app/Http/Controllers/Admin/Settings/AnchorSettingsController.php new file mode 100644 index 00000000000..a793efe8eff --- /dev/null +++ b/app/Http/Controllers/Admin/Settings/AnchorSettingsController.php @@ -0,0 +1,34 @@ +panel_url ?: null); + } + + public function update( + UpdateAnchorSettingsRequest $request, + AnchorSettings $settings, + ): AnchorSettingsData { + // Stored as '' rather than null so the setting's shape never changes; + // an empty value is what makes the cascade fall through to APP_URL. + $settings->panel_url = rtrim((string) $request->input('panel_url'), '/'); + $settings->save(); + + Audit::record( + AuditEvent::ADMIN_SETTINGS_ANCHOR_UPDATED, + properties: ['panel_url' => $settings->panel_url ?: null], + ); + + return new AnchorSettingsData($settings->panel_url ?: null); + } +} diff --git a/app/Http/Controllers/Admin/Settings/BandwidthSettingsController.php b/app/Http/Controllers/Admin/Settings/BandwidthSettingsController.php new file mode 100644 index 00000000000..b651bce6622 --- /dev/null +++ b/app/Http/Controllers/Admin/Settings/BandwidthSettingsController.php @@ -0,0 +1,51 @@ +global()); + } + + public function update( + UpdateBandwidthSettingsRequest $request, + BandwidthSettings $settings, + OveragePenaltyResolver $resolver, + ): BandwidthSettingsData { + $action = OveragePenaltyAction::from($request->input('overage_penalty.action')); + + $settings->overage_action = $action->value; + + // Leave the stored rate alone for `disconnect` — it is not part of that + // penalty, and preserving it means flipping back to throttle restores + // the operator's previous figure instead of a default. + if ($action === OveragePenaltyAction::THROTTLE) { + $settings->overage_rate = (int) $request->input('overage_penalty.rate'); + } + + $settings->save(); + + // No subject: this is panel-wide configuration, not an action on a record. + Audit::record( + AuditEvent::ADMIN_SETTINGS_BANDWIDTH_UPDATED, + properties: [ + 'overage_action' => $settings->overage_action, + 'overage_rate' => $settings->overage_rate, + ], + ); + + return new BandwidthSettingsData($resolver->global()); + } +} diff --git a/app/Http/Controllers/Admin/Settings/MailSettingsController.php b/app/Http/Controllers/Admin/Settings/MailSettingsController.php new file mode 100644 index 00000000000..ab82f06db1f --- /dev/null +++ b/app/Http/Controllers/Admin/Settings/MailSettingsController.php @@ -0,0 +1,154 @@ +present($settings, $configurator); + } + + public function update( + UpdateMailSettingsRequest $request, + MailSettings $settings, + MailConfigurator $configurator, + ): MailSettingsData { + $host = trim((string) $request->input('host')); + + if ($host === '') { + // Clearing the host clears the tier. Leaving a stale password encrypted in the + // settings table for a relay the panel no longer talks to would be a credential + // kept for no reason. + $settings->host = ''; + $settings->username = ''; + $settings->password = ''; + $settings->from_address = ''; + $settings->from_name = ''; + } else { + $settings->host = $host; + $settings->port = (int) $request->input('port'); + $settings->username = (string) $request->input('username', ''); + $settings->encryption = $request->enum('encryption', MailEncryption::class); + $settings->from_address = (string) $request->input('from_address'); + $settings->from_name = (string) $request->input('from_name'); + + // Absent means keep; present-but-empty means clear. The screen omits the key + // entirely when the admin does not touch the password field. + if ($request->has('password')) { + $settings->password = (string) $request->input('password', ''); + } + } + + $settings->save(); + + // The values, never the password — and never a "password" key at all, since even + // recording that one was set alongside a host tells the log more than it needs. + Audit::record( + AuditEvent::ADMIN_SETTINGS_MAIL_UPDATED, + properties: array_filter([ + 'host' => $settings->host ?: null, + 'port' => $settings->host ? $settings->port : null, + 'encryption' => $settings->host ? $settings->encryption->value : null, + 'from_address' => $settings->from_address ?: null, + 'cleared' => $settings->host === '' ?: null, + ], fn ($value) => $value !== null), + ); + + // Rebuild the runtime mailer so anything sending later in this request uses what was + // just saved rather than the config this process booted with. + $configurator->applyAndPurge(); + + return $this->present($settings, $configurator); + } + + /** + * Send a test message using the submitted (not necessarily saved) settings. + */ + public function test( + TestMailSettingsRequest $request, + MailSettings $settings, + MailConfigurator $configurator, + ) { + // A password the screen never displayed cannot be retyped, so an omitted key falls + // back to what is stored. That keeps "change the port and retest" a one-field edit. + $password = $request->has('password') + ? (string) $request->input('password', '') + : $settings->password; + + $recipient = (string) ($request->input('recipient') ?: $request->user()->email); + + $encryption = $request->enum('encryption', MailEncryption::class); + + $transport = $configurator->buildTransportConfig( + host: (string) $request->input('host'), + port: (int) $request->input('port'), + username: (string) $request->input('username', ''), + password: $password, + encryption: $encryption, + ); + + try { + $configurator->sendTest( + $recipient, + $transport, + (string) $request->input('from_address'), + (string) $request->input('from_name'), + $encryption, + ); + } catch (Throwable $e) { + // The transport's own message is the entire value of this endpoint — "Connection + // could not be established", "535 Authentication failed", "550 sender rejected" are + // each a different afternoon. Swallowing it for a tidy "test failed" would leave the + // operator exactly where they were before this screen existed. + Audit::record( + AuditEvent::ADMIN_SETTINGS_MAIL_TESTED, + properties: [ + 'host' => $request->input('host'), + 'recipient' => $recipient, + 'succeeded' => false, + ], + ); + + throw new BadRequestHttpException($e->getMessage(), $e); + } + + Audit::record( + AuditEvent::ADMIN_SETTINGS_MAIL_TESTED, + properties: [ + 'host' => $request->input('host'), + 'recipient' => $recipient, + 'succeeded' => true, + ], + ); + + return response()->json([ + 'data' => ['recipient' => $recipient], + ]); + } + + private function present(MailSettings $settings, MailConfigurator $configurator): MailSettingsData + { + return new MailSettingsData( + host: $settings->host, + port: $settings->port, + username: $settings->username, + encryption: $settings->encryption, + fromAddress: $settings->from_address, + fromName: $settings->from_name, + passwordSet: $settings->password !== '', + configured: $configurator->isConfigured(), + ); + } +} diff --git a/app/Http/Controllers/Admin/StorageBackupController.php b/app/Http/Controllers/Admin/StorageBackupController.php new file mode 100644 index 00000000000..e9ae30e53e6 --- /dev/null +++ b/app/Http/Controllers/Admin/StorageBackupController.php @@ -0,0 +1,49 @@ +is_locked) { + throw ValidationException::withMessages([ + 'backup' => 'That backup is locked. Unlock it before deleting it.', + ]); + } + + $properties = ['backup' => $backup->name, 'backup_uuid' => $backup->uuid]; + $server = $backup->server; + + $this->deletion->handle($backup); + + // Subject is the server, matching the client-side backup events, so an owner sees staff + // deleting their backup in the same feed as their own backup activity. + Audit::record(AuditEvent::ADMIN_BACKUP_DELETED, subject: $server, properties: $properties); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Admin/StorageConsumerController.php b/app/Http/Controllers/Admin/StorageConsumerController.php new file mode 100644 index 00000000000..57cc30f09ec --- /dev/null +++ b/app/Http/Controllers/Admin/StorageConsumerController.php @@ -0,0 +1,116 @@ +servers($storage), + backups: $this->backups($storage), + ); + } + + /** + * Servers by the space their disks take *on this storage*. + * + * Summed from `server_disks` rather than counted from `servers`, because a + * server can keep its boot disk on one storage and a data disk on another -- + * listing the whole server against both would double-count it. + */ + /** + * @param array $rows + * @return DataCollection + */ + private function collect(array $rows): DataCollection + { + return StorageConsumerData::collect($rows, DataCollection::class) + ->withoutWrapping(); + } + + /** @return DataCollection */ + private function servers(Storage $storage): DataCollection + { + $disks = ServerDisk::query() + ->where('storage_id', $storage->id) + ->with('server.user') + ->get() + ->groupBy('server_id'); + + $rows = $disks + ->map(function ($group) { + /** @var ServerDisk $first */ + $first = $group->first(); + $server = $first->server; + + if ($server === null) { + return null; + } + + return new StorageConsumerData( + id: $server->id, + routeKey: $server->uuid, + nodeId: null, + name: $server->name, + size: (int) $group->sum('size'), + owner: $server->user?->email, + detail: 'vmid '.$server->vmid, + // Deleting a server is offered, but the dialog makes the + // operator type its name -- see the client. + deletable: true, + ); + }) + ->filter() + ->sortByDesc(fn (StorageConsumerData $row) => $row->size) + ->values() + ->all(); + + return $this->collect($rows); + } + + /** @return DataCollection */ + private function backups(Storage $storage): DataCollection + { + $rows = Backup::query() + ->where('storage_id', $storage->id) + ->with('server') + ->get() + ->map(fn (Backup $backup) => new StorageConsumerData( + id: $backup->id, + routeKey: $backup->uuid, + nodeId: null, + name: $backup->name, + size: (int) ($backup->size ?? 0), + owner: $backup->server?->name, + detail: $backup->completed_at?->diffForHumans(), + // A locked backup is locked for a reason; saying so on the row + // beats offering a button that fails. + deletable: ! $backup->is_locked, + )) + ->sortByDesc(fn (StorageConsumerData $row) => $row->size) + ->values() + ->all(); + + return $this->collect($rows); + } +} diff --git a/app/Http/Controllers/Admin/StorageInventoryController.php b/app/Http/Controllers/Admin/StorageInventoryController.php new file mode 100644 index 00000000000..268bd0d6feb --- /dev/null +++ b/app/Http/Controllers/Admin/StorageInventoryController.php @@ -0,0 +1,50 @@ +whereHas('nodes') + ->withUsageSums() + // Ordered because the page prints these names in a row: without it + // the order is whatever Postgres returns, which is stable enough to + // look intentional and changes the moment the table does. + ->with(['nodes' => fn ($query) => $query->orderBy('nodes.display_name')]) + ->get(); + + return StorageEloquentData::collect( + $storages + // No `$viewedFrom`, so `sharedWith` names every node the storage + // reaches rather than "the others" -- which is what a list with + // no node in scope should show. + ->map(fn (Storage $storage) => StorageEloquentData::fromModel($storage)) + ->all(), + DataCollection::class, + ); + } +} diff --git a/app/Http/Controllers/Admin/TokenController.php b/app/Http/Controllers/Admin/TokenController.php index 14e83dee5ab..cd0f0f04b27 100644 --- a/app/Http/Controllers/Admin/TokenController.php +++ b/app/Http/Controllers/Admin/TokenController.php @@ -1,42 +1,102 @@ with('tokenable') - ->defaultSort('-id') - ->where('personal_access_tokens.type', ApiKeyType::APPLICATION->value) - ->paginate(min($request->query('per_page', 50), 100))->appends( + ->with('createdBy') + ->defaultSort('-id') + ->where('personal_access_tokens.type', ApiKeyType::APPLICATION->value) + ->paginate(min($request->query('per_page', 50), 100))->appends( $request->query(), ); - return fractal($tokens, new ApiKeyTransformer())->respond(); + return PaginationMeta::paginate($tokens, ApiKeyData::class); } public function store(StoreTokenRequest $request) { - $token = $request->user()->createToken($request->name, ApiKeyType::APPLICATION); + $newToken = $this->createApplicationToken->handle( + $request->user(), + $request->name, + $request->abilities(), + $request->allowedNetworks(), + ); + + if (! $newToken->accessToken instanceof PersonalAccessToken) { + throw new LogicException('Sanctum is not using the application personal access token model.'); + } + + $newToken->accessToken->loadMissing('createdBy'); + + // A panel-wide token is the broadest credential the system issues, so its abilities and + // network restrictions are recorded in full. The plaintext token never is. + Audit::record( + AuditEvent::ADMIN_TOKEN_CREATED, + subject: $newToken->accessToken, + properties: [ + 'name' => $newToken->accessToken->name, + 'abilities' => $newToken->accessToken->abilities, + 'allowed_networks' => $newToken->accessToken->allowed_networks, + ], + ); + + return ApiKeyData::fromModel($newToken->accessToken, $newToken->plainTextToken); + } + + public function update(UpdateTokenRequest $request, PersonalAccessToken $token) + { + abort_unless($token->type === ApiKeyType::APPLICATION, 404); + + $token->update(['allowed_networks' => $request->allowedNetworks()]); + $token->loadMissing('createdBy'); + + Audit::record( + AuditEvent::ADMIN_TOKEN_UPDATED, + subject: $token, + properties: [ + 'name' => $token->name, + 'allowed_networks' => $token->allowed_networks, + ], + ); - return fractal($token, new NewApiKeyTransformer())->respond(); + return ApiKeyData::fromModel($token); } public function destroy(PersonalAccessToken $token) { + abort_unless($token->type === ApiKeyType::APPLICATION, 404); + + $name = $token->name; + $token->delete(); - return $this->returnNoContent(); + Audit::record( + AuditEvent::ADMIN_TOKEN_DELETED, + subject: $token, + properties: ['name' => $name], + ); + + return response()->noContent(); } } diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index a915cff4362..5ae7abbb035 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -1,32 +1,38 @@ allowedFilters( [AllowedFilter::exact('id'), 'name', AllowedFilter::exact( 'email', - ), AllowedFilter::custom('*', new FiltersUserWildcard())], + ), AllowedFilter::custom('*', new FiltersUserWildcard)], ) + // The admin list is sortable by every column it shows. Sorts are named after the + // response's camelCase properties, since the table sends the column it sorted by. + ->allowedSorts([ + 'id', + 'name', + 'email', + AllowedSort::field('rootAdmin', 'root_admin'), + AllowedSort::field('serversCount', 'servers_count'), + AllowedSort::field('createdAt', 'created_at'), + ]) + ->defaultSort('name') ->paginate(min($request->query('per_page', 50), 100))->appends( $request->query(), ); - return fractal($users, new UserTransformer())->respond(); + return PaginationMeta::paginate($users, UserData::class); } + /** + * The whole account, for the detail page: counts, credential inventory, last sign-in and the + * resources it holds across the fleet. The list endpoint stays lean — none of this is worth + * computing fifty times a page. + */ public function show(User $user) { - $user->loadCount(['servers']); - - return fractal($user, new UserTransformer())->respond(); + return UserData::detail($user); } public function store(StoreUserRequest $request) { + $password = $request->input('password'); + $invited = $password === null || $password === ''; + $user = User::create([ 'name' => $request->name, 'email' => $request->email, - 'password' => Hash::make($request->password), + // An invited account still needs a value in a NOT NULL column, so it gets 64 random + // characters nobody has ever seen. It is not a password anyone can use — the account + // is unreachable until the invite is redeemed, which is the intended state. + 'password' => $invited ? Str::random(64) : $password, 'root_admin' => $request->root_admin, ])->loadCount(['servers']); - return fractal($user, new UserTransformer())->respond(); + Audit::record( + AuditEvent::ADMIN_USER_CREATED, + subject: $user, + properties: [ + 'email' => $user->email, + 'root_admin' => $user->root_admin, + 'invited' => $invited, + ], + ); + + $data = UserData::from($user); + + return $invited + ? ['data' => $data, 'invite' => $this->sendInvite($user)] + : $data; + } + + /** + * Issue a fresh invite for an account that has one outstanding, or never had one. + * + * Separate from `store` because the reasons to reach for it come later: the link expired, + * it went to a spam folder, or mail was not configured when the account was made and now is. + */ + public function invite(User $user) + { + return ['data' => $this->sendInvite($user)]; + } + + public function revokeInvite(User $user) + { + $this->invites->revoke($user); + + Audit::record(AuditEvent::ADMIN_USER_INVITE_REVOKED, subject: $user); + + return response()->noContent(); + } + + /** + * Mint a link, email it when there is a relay to email it with, and hand it back either way. + * + * The link is returned even on success, because mail is not proof of delivery and plenty of + * installs have no SMTP at all. An admin who can copy the link is never blocked by a mail + * configuration — which is what keeps this flow strictly better than emailing a password. + */ + private function sendInvite(User $user): UserInviteData + { + $token = $this->invites->issue($user); + $link = UserInviteService::url($token); + $ttl = (int) config('invites.ttl_days'); + + $emailed = $this->mail->isConfigured(); + + if ($emailed) { + $user->notify(new UserInvited($link, $ttl)); + } + + // The link itself is never recorded: it is a working credential until it is redeemed. + Audit::record( + AuditEvent::ADMIN_USER_INVITED, + subject: $user, + properties: ['emailed' => $emailed], + ); + + return new UserInviteData( + link: $link, + expiresAt: CarbonImmutable::now()->addDays($ttl), + emailed: $emailed, + ); } public function update(UpdateUserRequest $request, User $user) { - $this->connection->transaction(function () use ($request, $user) { - $requestRootAdmin = $request->boolean('root_admin'); - if ($user->root_admin !== $requestRootAdmin && ! $requestRootAdmin) { + // Demoting yourself is a one-way door: the screen you would fix it from is the one you + // just lost. Another admin can still do it, which is the point. + if ($user->is($request->user()) && $user->root_admin && ! $request->boolean('root_admin')) { + throw new BadRequestHttpException( + 'You cannot remove administrator access from your own account.', + ); + } + + DB::transaction(function () use ($request, $user) { + // Demoting an admin: revoke their API tokens so elevated access + // doesn't linger on tokens issued while they were an admin. + if ($user->root_admin && ! $request->boolean('root_admin')) { $user->tokens()->delete(); } + $wasAdmin = $user->root_admin; + $user->update([ 'name' => $request->name, 'email' => $request->email, 'root_admin' => $request->root_admin, - ...(is_null($request->password) ? [] : ['password' => Hash::make($request->password)]), + ...(is_null($request->password) ? [] : ['password' => $request->password]), ]); + + // Which fields moved, never their values — this covers a password reset performed on + // someone else's account, which is exactly the kind of thing the log exists for. + Audit::record( + AuditEvent::ADMIN_USER_UPDATED, + subject: $user, + properties: array_filter([ + 'email' => $user->wasChanged('email') ? $user->email : null, + 'name' => $user->wasChanged('name') ? $user->name : null, + 'password_changed' => $user->wasChanged('password') ?: null, + 'root_admin' => $wasAdmin !== $user->root_admin ? $user->root_admin : null, + ], fn ($value) => $value !== null), + ); }); $user->loadCount(['servers']); - return fractal($user, new UserTransformer())->respond(); + return UserData::from($user); } - public function destroy(User $user) + public function destroy(Request $request, User $user) { + if ($user->is($request->user())) { + throw new BadRequestHttpException( + 'You cannot delete the account you are signed in as.', + ); + } + $user->loadCount('servers'); if ($user->servers_count > 0) { @@ -94,25 +217,36 @@ public function destroy(User $user) ); } - $user->tokens()->delete(); + // Captured before the delete, and recorded after it succeeds: the subject morph will not + // resolve once the row is gone, so these properties and actor_label are the whole record. + $properties = ['name' => $user->name, 'email' => $user->email]; - $user->delete(); + $this->userDeletion->delete($user); - return $this->returnNoContent(); + Audit::record(AuditEvent::ADMIN_USER_DELETED, subject: $user, properties: $properties); + + return response()->noContent(); } public function getSSOToken(User $user) { - $token = $this->JWTService - ->setExpiresAt(CarbonImmutable::now()->addSeconds(15)) - ->setUser($user) - ->handle(config('app.key'), config('app.url'), $user->uuid); - - return new JsonResponse([ - 'data' => [ - 'user_id' => $user->id, - 'token' => $token->toString(), - ], - ]); + // A single-use, expiring Laravel signed URL — the integration redirects the browser + // straight to it. The `nonce` is consumed on first use (see Auth\SsoController) so a + // captured link cannot be replayed within its short lifetime. + $link = URL::temporarySignedRoute( + 'auth.sso.consume', + CarbonImmutable::now()->addSeconds(config('sso.link_ttl')), + ['uuid' => $user->uuid, 'nonce' => Str::random(40)], + ); + + // Admin-only in the catalog: this mints a link that logs the admin in as the user, and + // the fact of it should not surface in that user's own feed. The link itself is never + // recorded — it is a working credential until it is consumed. + Audit::record(AuditEvent::ADMIN_USER_SSO_TOKEN_GENERATED, subject: $user); + + return new SSOTokenData( + userId: $user->id, + link: $link, + ); } } diff --git a/app/Http/Controllers/Admin/UserCredentialController.php b/app/Http/Controllers/Admin/UserCredentialController.php new file mode 100644 index 00000000000..2f8e021b1ed --- /dev/null +++ b/app/Http/Controllers/Admin/UserCredentialController.php @@ -0,0 +1,183 @@ +apiKeys()->latest('id')->get(), + DataCollection::class, + ); + } + + public function destroyApiKey(Request $request, User $user, PersonalAccessToken $apiKey) + { + $this->denySelf($request, $user); + + $name = $apiKey->name; + + $apiKey->delete(); + + Audit::record( + AuditEvent::ACCOUNT_API_KEY_DELETED, + subject: $user, + properties: ['name' => $name], + ); + + return response()->noContent(); + } + + public function sshKeys(User $user) + { + return SSHKeyData::collect( + $user->sshKeys()->latest('id')->get(), + DataCollection::class, + ); + } + + public function destroySshKey(Request $request, User $user, SSHKey $sshKey) + { + $this->denySelf($request, $user); + + $name = $sshKey->name; + + $sshKey->delete(); + + Audit::record( + AuditEvent::ACCOUNT_SSH_KEY_DELETED, + subject: $user, + properties: ['name' => $name], + ); + + return response()->noContent(); + } + + public function passkeys(User $user) + { + return PasskeyData::collect( + $user->passkeys()->latest('id')->get(), + DataCollection::class, + ); + } + + public function destroyPasskey(Request $request, User $user, Passkey $passkey) + { + $this->denySelf($request, $user); + + $name = $passkey->name; + + $passkey->delete(); + + Audit::record( + AuditEvent::ACCOUNT_PASSKEY_DELETED, + subject: $user, + properties: ['name' => $name], + ); + + return response()->noContent(); + } + + public function oauthConnections(User $user) + { + return OAuthConnectionData::collect( + $user->oauthConnections()->latest('created_at')->get(), + DataCollection::class, + ); + } + + public function destroyOauthConnection( + Request $request, + User $user, + OAuthConnection $oauthConnection, + ) { + $this->denySelf($request, $user); + + $provider = $oauthConnection->provider; + + $oauthConnection->delete(); + + Audit::record( + AuditEvent::ACCOUNT_OAUTH_CONNECTION_DELETED, + subject: $user, + properties: ['provider' => $provider], + ); + + return response()->noContent(); + } + + /** + * Turn off the account's authenticator app — the lockout-recovery path, for the person who + * lost the phone and cannot get far enough into the panel to fix it themselves. + * + * Reuses {@see DisableAuthenticator} rather than clearing the columns here, so an account that + * still has a passkey keeps its recovery codes, and so the audit entry comes from the same + * Fortify event every other two-factor change does. + */ + public function destroyTwoFactor(Request $request, User $user) + { + $this->denySelf($request, $user); + + ($this->disableAuthenticator)($user); + + return response()->noContent(); + } + + /** + * An admin's own credentials are managed from `/security`, never from here. + * + * The client-side routes for all of this sit behind {@see RequireIdentityConfirmation}, + * which makes an unattended session or a stolen cookie insufficient to tear down the account's + * own second factor. This surface has no such gate — it is not the account's own session that + * authorises the change — so letting it point at the caller would be a way around that check + * rather than a convenience. + */ + private function denySelf(Request $request, User $user): void + { + if ($user->is($request->user())) { + throw new BadRequestHttpException( + 'Manage your own credentials from your account security page.', + ); + } + } +} diff --git a/app/Http/Controllers/Admin/VersionController.php b/app/Http/Controllers/Admin/VersionController.php new file mode 100644 index 00000000000..62c9d03c26a --- /dev/null +++ b/app/Http/Controllers/Admin/VersionController.php @@ -0,0 +1,32 @@ +status(); + } + + /** + * Checks now, on an admin's explicit request, rather than waiting for the + * next scheduled pass. This is the one path that fetches during a request; + * it is rate limited on the route because the ceiling that matters is + * GitHub's, not ours. + * + * @throws UpdateCheckFailedException + */ + public function check(UpdateCheckService $updates): UpdateStatusData + { + return $updates->check(); + } +} diff --git a/app/Http/Controllers/Anchor/EnrollmentController.php b/app/Http/Controllers/Anchor/EnrollmentController.php new file mode 100644 index 00000000000..f0668cb6d0f --- /dev/null +++ b/app/Http/Controllers/Anchor/EnrollmentController.php @@ -0,0 +1,147 @@ +string('token')->toString(); + + /* + * Which question is being asked is decided by the token's shape, not by + * which lookup happens to find a row. + * + * Looking up both and taking whichever hits would mean a mistyped + * rotation token falls through and gets evaluated as an attempt to + * enroll a stranger -- the two paths have very different consequences, + * so which one a request is on must not depend on a query missing. + */ + $installation = Str::startsWith($token, AnchorEnrollmentKeyService::TOKEN_PREFIX) + ? $this->selfRegister($request, $token) + : $this->rotate($token); + + return response()->json(['config' => $this->config($installation)]); + } + + /** A machine the panel has never seen, holding a valid enrollment key. */ + private function selfRegister(ConsumeEnrollmentRequest $request, string $token): AnchorEnrollment + { + $enrollment = $this->selfRegistration->register( + token: $token, + mode: $request->mode(), + report: $request->report(), + ); + + /* + * No actor: the enrolling machine is not a panel principal, and casting + * it as one would put a host in the same column as the admins. "Who + * let this in" is answered through the key named here, which leads to + * the admin who cut it. + */ + Audit::record( + AuditEvent::ADMIN_ANCHOR_SELF_ENROLLED, + subject: $enrollment, + properties: [ + 'name' => $enrollment->name, + 'mode' => $enrollment->mode->value, + 'enrollment_key' => $enrollment->enrollmentKey?->name, + 'hostname' => $enrollment->reported('hostname'), + 'source_ip' => $enrollment->reported('observed_source_ip'), + ], + ); + + return $enrollment; + } + + /** + * An installation the panel already has a row for, being re-keyed. + * + * Looks in both tables that can hold one. A node's columns are prefixed and + * a relay's are not, which is the price of the node and its agent being one + * record -- paid here, in one place, rather than by every reader. + */ + private function rotate(string $token): Node|Relay + { + return DB::transaction(function () use ($token) { + $hash = hash('sha256', $token); + + $node = Node::where('agent_enrollment_token_hash', $hash)->lockForUpdate()->first(); + $relay = $node === null + ? Relay::where('enrollment_token_hash', $hash)->lockForUpdate()->first() + : null; + + $installation = $node ?? $relay; + $expiresAt = $node?->agent_enrollment_expires_at ?? $relay?->enrollment_expires_at; + + if ($installation === null || $expiresAt?->isPast()) { + throw new UnprocessableEntityHttpException('The enrollment token is invalid or expired.'); + } + + $prefix = $node !== null ? 'agent_' : ''; + + $installation->update([ + $prefix.'enrollment_token_hash' => null, + $prefix.'enrollment_expires_at' => null, + $prefix.'enrolled_at' => now(), + /* + * Enrolling is the only path that hands the secret out, so it + * is the only place that can rotate it -- and it has to, or the + * enrollment token is a fresh courier delivering the same + * payload forever: any copy of anchor.toml that ever leaked + * stays valid, and re-enrolling, the one action that looks like + * remediation, hands the identical secret back. + * + * Rotating here makes "reissue the command, run it again" the + * remediation. The cost is deliberate: the previous + * installation's bearer stops matching immediately and its + * console sessions, signed with the old secret, die with it. + */ + $prefix.'secret' => Str::random(64), + ]); + + return $installation; + }); + } + + /** + * What the agent writes to disk. + * + * `public_url` is deliberately absent. It describes how the *panel* reaches + * the agent, the agent has never read it (it serves the same routes + * regardless), and mirroring it into the TOML meant a correction could not + * be made without re-enrolling the box. + * + * @return array + */ + private function config(Node|Relay|AnchorEnrollment $installation): array + { + $mode = $installation->anchorMode(); + + return [ + 'mode' => $mode->value, + 'listen_addr' => $mode === AnchorMode::AGENT ? '127.0.0.1:2115' : '0.0.0.0:2115', + 'installation_id' => $installation->anchorUuid(), + 'secret' => $installation->anchorSecret(), + 'panel_url' => $installation->anchorPanelUrl().'/', + 'agent' => ['qm_path' => '/usr/sbin/qm'], + ]; + } +} diff --git a/app/Http/Controllers/Anchor/HeartbeatController.php b/app/Http/Controllers/Anchor/HeartbeatController.php new file mode 100644 index 00000000000..42df501840d --- /dev/null +++ b/app/Http/Controllers/Anchor/HeartbeatController.php @@ -0,0 +1,35 @@ +attributes->get('anchor'); + + // A mismatch means this credential is being presented by something + // other than the installation it was issued to. + if ($request->string('mode')->toString() !== $installation->anchorMode()->value) { + throw ValidationException::withMessages([ + 'mode' => 'The reported mode does not match this Anchor installation.', + ]); + } + + $installation->recordAnchorHeartbeat([ + 'version' => $request->string('version')->toString(), + 'protocol_min' => $request->integer('protocol.min'), + 'protocol_max' => $request->integer('protocol.max'), + 'capabilities' => $request->input('capabilities'), + ]); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/ApiController.php b/app/Http/Controllers/ApiController.php deleted file mode 100644 index d322d0b00d0..00000000000 --- a/app/Http/Controllers/ApiController.php +++ /dev/null @@ -1,13 +0,0 @@ -session()); + + return response()->json([ + 'confirmed' => $expiresIn > 0, + 'expires_in' => $expiresIn > 0 ? $expiresIn : null, + ]); + } + + public function generatePasskeyAuthOptions(Request $request) + { + $options = $this->generateOptionsAction->execute(); + + // Its own key, not the guest login flow's `passkeys.authentication-options`: + // these are separate ceremonies with separate lifetimes, and a challenge + // minted to prove presence now must never be satisfiable by one minted + // to log in. + $request->session()->put('passkeys.identity-options', $options); + + return $options; + } + + public function store(ConfirmIdentityRequest $request) + { + $user = $request->user(); + if (! $user instanceof User) { + throw new InvalidAuthenticationMethodException; + } + + if ($request->filled('passkey')) { + // pull, not get: identity confirmation exists to prove someone is + // present *now*, so its challenge is strictly single use. Left in the + // session it stayed valid, and the same assertion could re-confirm + // identity after the 5-minute window lapsed — replaying presence is + // exactly what the gate is meant to prevent. + $options = $request->session()->pull('passkeys.identity-options'); + + if (! is_string($options)) { + throw new InvalidPasskeyException; + } + + /** @var Passkey|null $passkey (config binds passkeys.models.passkey to our subclass) */ + $passkey = $this->findPasskeyAction->execute($request->input('passkey'), $options); + + if (! $passkey || $passkey->user->id !== $user->id) { + throw new InvalidPasskeyException; + } + } elseif ($request->filled('password')) { + // Handle password confirmation + $confirmed = auth()->validate([ + 'email' => $user->email, + 'password' => $request->input('password'), + ]); + + if (! $confirmed) { + return app(FailedPasswordConfirmationResponse::class); + } + } else { + throw new InvalidAuthenticationMethodException; + } + + IdentityConfirmation::confirm($request->session()); + + return $this->show($request); + } +} diff --git a/app/Http/Controllers/Auth/InviteController.php b/app/Http/Controllers/Auth/InviteController.php new file mode 100644 index 00000000000..deb694209cc --- /dev/null +++ b/app/Http/Controllers/Auth/InviteController.php @@ -0,0 +1,73 @@ +invites->resolve($token); + + if ($invite === null) { + // Unknown, spent and expired are one answer. Telling them apart would confirm that a + // guessed token once meant something. + throw new NotFoundHttpException('This invitation is no longer valid.'); + } + + return response()->json([ + 'data' => [ + 'name' => $invite->user->name, + 'email' => $invite->user->email, + 'expiresAt' => $invite->expires_at->toIso8601String(), + ], + ]); + } + + /** + * Set the password and sign them in. + * + * Signing in immediately is the point of arriving here: the alternative is bouncing someone + * who has just proved they hold the invite to a login form to retype what they typed a + * second ago. + */ + public function store(AcceptInviteRequest $request, string $token) + { + $invite = $this->invites->resolve($token); + + if ($invite === null) { + throw new NotFoundHttpException('This invitation is no longer valid.'); + } + + $user = $this->invites->accept($invite, $request->string('password')->toString()); + + Auth::login($user); + + $request->session()->regenerate(); + + // Recorded against the account itself: this is the moment it becomes usable, and the + // actor is the account's own owner rather than the admin who created it. + Audit::record( + AuditEvent::AUTH_INVITE_ACCEPTED, + subject: $user, + properties: ['ip' => $request->ip()], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php deleted file mode 100644 index a9d00a70ef2..00000000000 --- a/app/Http/Controllers/Auth/LoginController.php +++ /dev/null @@ -1,46 +0,0 @@ -view->make('app'); - } - - public function authorizeToken(Request $request) - { - try { - $token = $this->JWTService->decode(config('app.key'), $request->token); - } catch (InvalidJWTException) { - throw new UnauthorizedHttpException('', 'Invalid JWT token'); - } - - /** @var User $user */ - $user = User::where('uuid', '=', $token->claims()->get('user_uuid'))->first(); - - if (!$user) { - throw new UnauthorizedHttpException('', 'Invalid JWT claims'); - } - - Auth::loginUsingId($user->id); - - $request->session()->regenerate(); - - return redirect()->route('index'); - } -} diff --git a/app/Http/Controllers/Auth/OAuthController.php b/app/Http/Controllers/Auth/OAuthController.php new file mode 100644 index 00000000000..d7c6323147d --- /dev/null +++ b/app/Http/Controllers/Auth/OAuthController.php @@ -0,0 +1,111 @@ +service->ensureEnabled($provider); + + $intended = (string) $request->query('intended', ''); + // Only same-origin relative paths — never an absolute URL an attacker could smuggle in as + // an open-redirect after login. + $request->session()->put( + 'oauth.intended', + str_starts_with($intended, '/') && ! str_starts_with($intended, '//') ? $intended : '/', + ); + + return Socialite::driver($provider)->redirect(); + } + + /** + * Handle the provider's redirect back. Logged-in → link; logged-out → login/provision. + */ + public function callback(Request $request, string $provider): RedirectResponse + { + $this->service->ensureEnabled($provider); + + try { + $socialiteUser = Socialite::driver($provider)->user(); + } catch (InvalidStateException) { + // Stale/forged state (e.g. the user sat on the provider page past the session, or an + // out-of-band callback). Not an error worth a stack trace — send them back to retry. + return $this->failLogin('oauth_invalid_state'); + } + + if (Auth::check()) { + return $this->handleLink($request, $provider, $socialiteUser); + } + + return $this->handleLogin($request, $provider, $socialiteUser); + } + + private function handleLogin(Request $request, string $provider, \Laravel\Socialite\Contracts\User $socialiteUser): RedirectResponse + { + try { + $user = $this->service->resolveForLogin($provider, $socialiteUser); + } catch (HasErrorCode $e) { + return $this->failLogin($e->errorCode()); + } + + Auth::guard('web')->login($user); + $request->session()->regenerate(); + + $intended = (string) $request->session()->pull('oauth.intended', '/'); + + return redirect()->to($intended === '' ? '/' : $intended); + } + + private function handleLink(Request $request, string $provider, \Laravel\Socialite\Contracts\User $socialiteUser): RedirectResponse + { + /** @var User $user */ + $user = $request->user(); + + $request->session()->forget('oauth.intended'); + + try { + $this->service->linkToUser($user, $provider, $socialiteUser); + } catch (HasErrorCode $e) { + return redirect()->to(self::ACCOUNT_SECURITY_PATH.'?oauth_error='.$e->errorCode()); + } + + return redirect()->to(self::ACCOUNT_SECURITY_PATH.'?oauth_linked='.$provider); + } + + private function failLogin(string $code): RedirectResponse + { + return redirect()->to(self::LOGIN_PATH.'?oauth_error='.$code); + } +} diff --git a/app/Http/Controllers/Auth/PasskeyLoginController.php b/app/Http/Controllers/Auth/PasskeyLoginController.php new file mode 100644 index 00000000000..2d5d0cc26f3 --- /dev/null +++ b/app/Http/Controllers/Auth/PasskeyLoginController.php @@ -0,0 +1,56 @@ +generateOptionsAction->execute(); + + $request->session()->put('passkeys.authentication-options', $options); + + return $options; + } + + public function store(Request $request) + { + // pull, not get: a challenge is single use. Leaving it in the session + // kept it valid indefinitely, so a captured assertion stayed replayable + // against the same session — the one thing the challenge exists to stop. + // The is_string guard covers a verify with no create before it; + // execute() types the options non-nullable, so null was a TypeError and + // a 500 rather than a rejected attempt. + $options = $request->session()->pull('passkeys.authentication-options'); + + if (! is_string($options)) { + throw new InvalidPasskeyException; + } + + $passkey = $this->findPasskeyAction->execute($request->getContent(), $options); + + if (! $passkey) { + throw new InvalidPasskeyException; + } + + /** @var Passkey $passkey (config binds passkeys.models.passkey to our subclass) */ + $user = $passkey->user; + + auth()->login($user); + + $request->session()->regenerate(); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Auth/SecondFactorChallengeController.php b/app/Http/Controllers/Auth/SecondFactorChallengeController.php new file mode 100644 index 00000000000..0d489b14586 --- /dev/null +++ b/app/Http/Controllers/Auth/SecondFactorChallengeController.php @@ -0,0 +1,83 @@ +challengedUser($request); + + return response()->json([ + 'authenticator' => $user->hasEnabledTwoFactorAuthentication(), + 'passkey' => $user->passkeys()->exists(), + 'recovery' => filled($user->two_factor_recovery_codes), + ]); + } + + public function create(Request $request) + { + $user = $this->challengedUser($request); + + if (! $user->passkeys()->exists()) { + throw new InvalidPasskeyException; + } + + $options = $this->generateOptionsAction->execute(); + + $request->session()->put('passkeys.second-factor-options', $options); + + return $options; + } + + public function store(Request $request) + { + $user = $this->challengedUser($request); + $options = $request->session()->pull('passkeys.second-factor-options'); + + if (! is_string($options)) { + throw new InvalidPasskeyException; + } + + /** @var Passkey|null $passkey Config binds the package action to our model subclass. */ + $passkey = $this->findPasskeyAction->execute($request->getContent(), $options); + + // The challenge is for the password-validated login.id, not whichever + // account happens to own the asserted credential. + if (! $passkey || ! $passkey->user->is($user)) { + throw new InvalidPasskeyException; + } + + $remember = $request->session()->pull('login.remember', false); + $request->session()->forget('login.id'); + + $this->guard->login($user, $remember); + $request->session()->regenerate(); + + return response()->noContent(); + } + + private function challengedUser(Request $request): User + { + $id = $request->session()->get('login.id'); + $user = $id ? $this->guard->getProvider()->retrieveById($id) : null; + + abort_unless($user instanceof User, 403); + + return $user; + } +} diff --git a/app/Http/Controllers/Auth/SsoController.php b/app/Http/Controllers/Auth/SsoController.php new file mode 100644 index 00000000000..d7d88e1fd7e --- /dev/null +++ b/app/Http/Controllers/Auth/SsoController.php @@ -0,0 +1,52 @@ +query('nonce'); + + if ($nonce === '' || ! Cache::add("sso-nonce:{$nonce}", true, now()->addSeconds(config('sso.link_ttl') + 60))) { + throw new UnauthorizedHttpException('', 'This single sign-on link has already been used or is invalid.'); + } + + $user = User::where('uuid', '=', $uuid)->first(); + + if (! $user instanceof User) { + throw new UnauthorizedHttpException('', 'The single sign-on link references an unknown user.'); + } + + Auth::loginUsingId($user->id); + + $request->session()->regenerate(); + + // Audit trail: SSO bypasses password/2FA, so record every successful consumption. + Log::channel(config('sso.audit_channel'))->info('SSO deep link consumed', [ + 'user_id' => $user->id, + 'user_uuid' => $user->uuid, + 'ip' => $request->ip(), + 'user_agent' => $request->userAgent(), + ]); + + return redirect()->route('index'); + } +} diff --git a/app/Http/Controllers/Base/AvatarController.php b/app/Http/Controllers/Base/AvatarController.php new file mode 100644 index 00000000000..9c1d71ab09e --- /dev/null +++ b/app/Http/Controllers/Base/AvatarController.php @@ -0,0 +1,45 @@ + wants a failed image, not a login page, and + // a signed-out scanner learns nothing about which accounts have one. + abort_unless($request->user(), 404); + + $disk = Filesystem::disk($this->avatars->diskName()); + $file = "avatars/{$path}"; + + abort_unless($disk->exists($file), 404); + + return $disk->response($file, null, [ + 'Content-Type' => 'image/webp', + 'Cache-Control' => 'private, max-age=31536000, immutable', + ]); + } +} diff --git a/app/Http/Controllers/Base/IndexController.php b/app/Http/Controllers/Base/IndexController.php index 0d8df42f455..3cac5795431 100644 --- a/app/Http/Controllers/Base/IndexController.php +++ b/app/Http/Controllers/Base/IndexController.php @@ -1,20 +1,20 @@ view->make('app', [ 'siteConfiguration' => [ 'version' => config('app.version'), + // Surfaced so the login screen can render "Continue with " buttons and + // the account page its connect actions. Only enabled+configured providers appear. + 'oauthProviders' => collect($this->oauth->enabledProviders()) + ->map(fn (string $label, string $id) => ['id' => $id, 'label' => $label]) + ->values() + ->all(), ], ]); } diff --git a/app/Http/Controllers/Base/LocaleController.php b/app/Http/Controllers/Base/LocaleController.php deleted file mode 100644 index 3ce035a0716..00000000000 --- a/app/Http/Controllers/Base/LocaleController.php +++ /dev/null @@ -1,97 +0,0 @@ - and contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -namespace Convoy\Http\Controllers\Base; - -use Convoy\Http\Requests\Base\LocaleRequest; -use Illuminate\Http\Request; -use Illuminate\Http\JsonResponse; -use Illuminate\Translation\Translator; -use Convoy\Http\Controllers\Controller; -use Illuminate\Contracts\Translation\Loader; - -class LocaleController extends Controller -{ - protected Loader $loader; - - public function __construct(Translator $translator) - { - $this->loader = $translator->getLoader(); - } - - /** - * Returns translation data given a specific locale and namespace. - */ - public function __invoke(LocaleRequest $request): JsonResponse - { - $locales = explode(' ', $request->input('locale') ?? ''); - $namespaces = explode(' ', $request->input('namespace') ?? ''); - - $response = []; - foreach ($locales as $locale) { - $response[$locale] = []; - foreach ($namespaces as $namespace) { - $response[$locale][$namespace] = $this->i18n( - $this->loader->load($locale, str_replace('.', '/', $namespace)) - ); - } - } - - return new JsonResponse($response, 200, [ - // Cache this in the browser for an hour, and allow the browser to use a stale - // cache for up to a day after it was created while it fetches an updated set - // of translation keys. - 'Cache-Control' => 'public, max-age=3600, stale-while-revalidate=86400', - 'ETag' => md5(json_encode($response, JSON_THROW_ON_ERROR)), - ]); - } - - /** - * Convert standard Laravel translation keys that look like ":foo" - * into key structures that are supported by the front-end i18n - * library, like "{{foo}}". - */ - protected function i18n(array $data): array - { - foreach ($data as $key => $value) { - if (is_array($value)) { - $data[$key] = $this->i18n($value); - } else { - // Find a Laravel style translation replacement in the string and replace it with - // one that the front-end is able to use. This won't always be present, especially - // for complex strings or things where we'd never have a backend component anyways. - // - // For example: - // "Hello :name, the :notifications.0.title notification needs :count actions :foo.0.bar." - // - // Becomes: - // "Hello {{name}}, the {{notifications.0.title}} notification needs {{count}} actions {{foo.0.bar}}." - $data[$key] = preg_replace('/:([\w.-]+\w)([^\w:]?|$)/m', '{{$1}}$2', $value); - } - } - - return $data; - } -} diff --git a/app/Http/Controllers/Client/Account/ApiKeyController.php b/app/Http/Controllers/Client/Account/ApiKeyController.php new file mode 100644 index 00000000000..0a79a4d2efe --- /dev/null +++ b/app/Http/Controllers/Client/Account/ApiKeyController.php @@ -0,0 +1,78 @@ +where('type', ApiKeyType::ACCOUNT->value) + ->whereMorphedTo('tokenable', $request->user()) + ->latest('id') + ->get(); + + return ApiKeyData::collect($tokens, DataCollection::class); + } + + public function store(StoreApiKeyRequest $request) + { + $newToken = $this->createAccountToken->handle($request->user(), $request->name, $request->abilities()); + + if (! $newToken->accessToken instanceof PersonalAccessToken) { + throw new LogicException('Sanctum is not using the application personal access token model.'); + } + + Audit::record( + AuditEvent::ACCOUNT_API_KEY_CREATED, + subject: $newToken->accessToken, + properties: [ + 'name' => $newToken->accessToken->name, + 'abilities' => $newToken->accessToken->abilities, + ], + ); + + return ApiKeyData::fromModel($newToken->accessToken, $newToken->plainTextToken); + } + + public function destroy(Request $request, PersonalAccessToken $apiKey) + { + // 404 (not 403) on someone else's or a non-account token, so a token id can't be probed. + if ( + $apiKey->type !== ApiKeyType::ACCOUNT + || ! $apiKey->tokenable()->is($request->user()) + ) { + throw new NotFoundHttpException; + } + + $name = $apiKey->name; + + $apiKey->delete(); + + // Subject is the acting user, not the token: the token row is gone, and this belongs in + // the account's own security history. + Audit::record( + AuditEvent::ACCOUNT_API_KEY_DELETED, + subject: $request->user(), + properties: ['name' => $name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Client/Account/AvatarController.php b/app/Http/Controllers/Client/Account/AvatarController.php new file mode 100644 index 00000000000..91bf84db50a --- /dev/null +++ b/app/Http/Controllers/Client/Account/AvatarController.php @@ -0,0 +1,42 @@ +avatars->store( + $request->user(), + $request->file('avatar'), + AvatarCropData::fromRequest($request), + ); + + Audit::record(AuditEvent::ACCOUNT_AVATAR_UPDATED, subject: $user); + + return UserData::forSelf($user, $this->policy->for($user)); + } + + public function destroy(DeleteAvatarRequest $request) + { + $user = $this->avatars->remove($request->user()); + + Audit::record(AuditEvent::ACCOUNT_AVATAR_UPDATED, subject: $user); + + return UserData::forSelf($user, $this->policy->for($user)); + } +} diff --git a/app/Http/Controllers/Client/Account/OAuthConnectionController.php b/app/Http/Controllers/Client/Account/OAuthConnectionController.php new file mode 100644 index 00000000000..30741d3a0af --- /dev/null +++ b/app/Http/Controllers/Client/Account/OAuthConnectionController.php @@ -0,0 +1,49 @@ +where('user_id', '=', $request->user()->id) + ->latest('created_at') + ->get(); + + return OAuthConnectionData::collect( + $connections->map(fn (OAuthConnection $connection) => OAuthConnectionData::fromModel($connection)), + DataCollection::class, + ); + } + + /** Unlink a provider from the account. */ + public function destroy(Request $request, OAuthConnection $oauthConnection) + { + // 404 (not 403) on someone else's connection, so a row id can't be probed. + if ($oauthConnection->user_id !== $request->user()->id) { + throw new NotFoundHttpException; + } + + $provider = $oauthConnection->provider; + + $oauthConnection->delete(); + + Audit::record( + AuditEvent::ACCOUNT_OAUTH_CONNECTION_DELETED, + subject: $request->user(), + properties: ['provider' => $provider], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Client/Account/ProfileController.php b/app/Http/Controllers/Client/Account/ProfileController.php new file mode 100644 index 00000000000..cc6ac91c606 --- /dev/null +++ b/app/Http/Controllers/Client/Account/ProfileController.php @@ -0,0 +1,59 @@ +user(); + + $user->update($request->validated()); + + if ($user->wasChanged()) { + Audit::record( + AuditEvent::ACCOUNT_PROFILE_UPDATED, + subject: $user, + properties: ['changed' => array_keys($user->getChanges())], + ); + } + + return UserData::forSelf($user, $this->policy->for($user)); + } + + public function updateEmail(UpdateEmailRequest $request) + { + $user = $request->user(); + + $user->update($request->validated()); + + if ($user->wasChanged()) { + Audit::record( + AuditEvent::ACCOUNT_PROFILE_UPDATED, + subject: $user, + properties: ['changed' => array_keys($user->getChanges())], + ); + } + + return UserData::forSelf($user, $this->policy->for($user)); + } +} diff --git a/app/Http/Controllers/Client/Account/SSHKeyController.php b/app/Http/Controllers/Client/Account/SSHKeyController.php new file mode 100644 index 00000000000..415045a71f9 --- /dev/null +++ b/app/Http/Controllers/Client/Account/SSHKeyController.php @@ -0,0 +1,56 @@ +user()->sshKeys()->latest('id')->get(), + DataCollection::class, + ); + } + + public function store(StoreSSHKeyRequest $request) + { + $key = $request->user()->sshKeys()->create($request->validated()); + + Audit::record( + AuditEvent::ACCOUNT_SSH_KEY_CREATED, + subject: $request->user(), + properties: ['name' => $key->name], + ); + + return SSHKeyData::fromModel($key); + } + + public function destroy(Request $request, SSHKey $sshKey) + { + // 404 (not 403) on someone else's key, so a key id can't be probed. + if ($sshKey->user_id !== $request->user()->id) { + throw new NotFoundHttpException; + } + + $name = $sshKey->name; + + $sshKey->delete(); + + Audit::record( + AuditEvent::ACCOUNT_SSH_KEY_DELETED, + subject: $request->user(), + properties: ['name' => $name], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Client/Account/SessionRecordController.php b/app/Http/Controllers/Client/Account/SessionRecordController.php new file mode 100644 index 00000000000..3963238e268 --- /dev/null +++ b/app/Http/Controllers/Client/Account/SessionRecordController.php @@ -0,0 +1,76 @@ +session()->getId(); + $handler = $request->session()->getHandler(); + + $records = SessionRecord::query() + ->where('user_id', $request->user()->id) + ->latest('last_active_at') + ->get(); + + // Reconcile against the session store: Redis is the source of truth for what's actually + // logged in, so drop (and delete) any row whose underlying session has expired or been + // evicted. This keeps the list from ever showing a session that no longer exists, and + // self-heals the metadata table on read. + [$live, $stale] = $records->partition( + fn (SessionRecord $record) => $record->session_id === $currentId + || $handler->read($record->session_id) !== '' + ); + + if ($stale->isNotEmpty()) { + SessionRecord::query()->whereKey($stale->modelKeys())->delete(); + } + + return SessionRecordData::collect( + $live->map(fn (SessionRecord $record) => SessionRecordData::fromModel($record, $currentId)), + DataCollection::class, + ); + } + + public function destroy(Request $request, SessionRecord $sessionRecord) + { + // 404 (not 403) on someone else's session, so a row id can't be probed. + if ($sessionRecord->user_id !== $request->user()->id) { + throw new NotFoundHttpException; + } + + // Revoking the current session is just a logout; leave that to the logout endpoint so the + // response can also clear the cookie. + if ($sessionRecord->session_id === $request->session()->getId()) { + abort(422, 'You cannot revoke the session you are currently using; log out instead.'); + } + + // Kill the actual session in the store (Redis) so the other device is logged out, and drop + // the metadata row — kept consistent by the shared revocation service. + $ipAddress = $sessionRecord->ip_address; + + $this->revocation->revoke($sessionRecord); + + Audit::record( + AuditEvent::ACCOUNT_SESSION_REVOKED, + subject: $request->user(), + properties: ['ip' => $ipAddress], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Client/AuthenticatorStatusController.php b/app/Http/Controllers/Client/AuthenticatorStatusController.php new file mode 100644 index 00000000000..17073f53278 --- /dev/null +++ b/app/Http/Controllers/Client/AuthenticatorStatusController.php @@ -0,0 +1,21 @@ +json([ + // Defer to Fortify rather than reading `two_factor_secret` here: + // with confirmation enabled a secret alone is not enabled, and + // Keep this authenticator-specific even though the account-level + // second-factor check also accepts a passkey. Checking the secret + // directly would still report an abandoned setup as enabled. + 'enabled' => $request->user()->hasEnabledTwoFactorAuthentication(), + ]); + } +} diff --git a/app/Http/Controllers/Client/IndexController.php b/app/Http/Controllers/Client/IndexController.php deleted file mode 100644 index d5df0be13f4..00000000000 --- a/app/Http/Controllers/Client/IndexController.php +++ /dev/null @@ -1,42 +0,0 @@ -user(); - - $builder = QueryBuilder::for(Server::query()) - ->with(['addresses']) - ->allowedFilters(['name']); - - $type = $request->input('type'); - - if ($type === 'all') { - if (!$user->root_admin) { - $builder = $builder->whereRaw('1 = 2'); - } - } else { - $builder = $builder->where('servers.user_id', $user->id); - } - - $servers = $builder->paginate(min($request->query('per_page', 50), 100))->appends( - $request->query(), - ); - - return fractal($servers, new ServerTransformer())->respond(); - } -} diff --git a/app/Http/Controllers/Client/PasskeyController.php b/app/Http/Controllers/Client/PasskeyController.php new file mode 100644 index 00000000000..901ad7c55eb --- /dev/null +++ b/app/Http/Controllers/Client/PasskeyController.php @@ -0,0 +1,113 @@ +user()->passkeys, DataCollection::class); + } + + public function create(Request $request) + { + $options = $this->generateOptionsAction->execute($request->user()); + + $request->session()->put('passkeys.registration-options', $options); + + return $options; + } + + public function store(Request $request, GenerateNewRecoveryCodes $generateRecoveryCodes) + { + $recoveryCodesCreated = empty($request->user()->two_factor_recovery_codes); + $passkey = $this->storeAction->execute( + authenticatable: $request->user(), + passkeyJson: $request->getContent(), + passkeyOptionsJson: $request->session()->get('passkeys.registration-options'), + hostName: $request->getHost(), + ); + + if ($recoveryCodesCreated) { + $generateRecoveryCodes($request->user()); + } + + Audit::record( + AuditEvent::ACCOUNT_PASSKEY_CREATED, + subject: $request->user(), + properties: [ + 'name' => $passkey->name, + // Worth recording separately: it means the account gained its first second factor, + // not just another one. + 'recovery_codes_created' => $recoveryCodesCreated, + ], + ); + + return response()->json([ + 'data' => PasskeyData::from($passkey), + 'recovery_codes' => $recoveryCodesCreated + ? json_decode(Fortify::currentEncrypter()->decrypt( + $request->user()->fresh()->two_factor_recovery_codes, + ), true) + : null, + ]); + } + + public function rename(RenamePasskeyRequest $request, Passkey $passkey) + { + $previousName = $passkey->name; + + $passkey->update($request->validated()); + + Audit::record( + AuditEvent::ACCOUNT_PASSKEY_RENAMED, + subject: $request->user(), + properties: ['from' => $previousName, 'to' => $passkey->name], + ); + + return PasskeyData::from($passkey); + } + + public function destroy(Passkey $passkey) + { + $user = $passkey->user; + $name = $passkey->name; + $passkey->delete(); + + $secondFactorRemoved = ! $user->passkeys()->exists() && empty($user->two_factor_secret); + + if ($secondFactorRemoved) { + $user->forceFill(['two_factor_recovery_codes' => null])->save(); + } + + Audit::record( + AuditEvent::ACCOUNT_PASSKEY_DELETED, + subject: $user, + properties: [ + 'name' => $name, + // True means the account no longer has any second factor at all. + 'left_without_second_factor' => $secondFactorRemoved, + ], + ); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Client/PasswordController.php b/app/Http/Controllers/Client/PasswordController.php new file mode 100644 index 00000000000..94dba9627fd --- /dev/null +++ b/app/Http/Controllers/Client/PasswordController.php @@ -0,0 +1,43 @@ +user(); + + // Cycle the remember token in the same write as the password: a "remember me" cookie + // authenticates on its own, so leaving it alone would let an evicted device walk straight + // back in and make the eviction below cosmetic. + $user->forceFill([ + 'password' => $request->string('password')->toString(), + 'remember_token' => Str::random(60), + ])->save(); + + // Changing a password is what someone does when they believe they are compromised, so it + // has to evict the attacker rather than only change what a future login needs. Nothing + // else does: `auth.session` is only on the SPA shell routes, so a stolen cookie driving + // the client API alone is never checked against the new hash. + $this->revocation->revokeOtherSessionsForUser($user, $request->session()->getId()); + + Audit::record(AuditEvent::ACCOUNT_PASSWORD_UPDATED, subject: $user); + + $user->notify(new PasswordChanged($request->ip())); + + return response()->noContent(); + } +} diff --git a/app/Http/Controllers/Client/RecoveryCodeController.php b/app/Http/Controllers/Client/RecoveryCodeController.php new file mode 100644 index 00000000000..a671365a18f --- /dev/null +++ b/app/Http/Controllers/Client/RecoveryCodeController.php @@ -0,0 +1,56 @@ +json([ + 'enabled' => filled($request->user()->two_factor_recovery_codes), + ]); + } + + public function index(Request $request) + { + if (! $request->user()->two_factor_recovery_codes) { + return []; + } + + return response()->json(json_decode(Fortify::currentEncrypter()->decrypt( + $request->user()->two_factor_recovery_codes, + ), true)); + } + + public function store(Request $request, GenerateNewRecoveryCodes $generate) + { + $generate($request->user()); + + Audit::record(AuditEvent::ACCOUNT_RECOVERY_CODES_REGENERATED, subject: $request->user()); + + return app(RecoveryCodesGeneratedResponse::class); + } +} diff --git a/app/Http/Controllers/Client/Servers/ActivityController.php b/app/Http/Controllers/Client/Servers/ActivityController.php deleted file mode 100644 index 9ae0183ed6d..00000000000 --- a/app/Http/Controllers/Client/Servers/ActivityController.php +++ /dev/null @@ -1,24 +0,0 @@ -activity()) - ->with('actor') - ->allowedSorts(['created_at', 'updated_at']) - ->allowedFilters(['event', 'batch', 'status']) - ->paginate(min($request->query('per_page', 25), 100)) - ->appends($request->query()); - - return fractal($activity, new ActivityLogTransformer())->respond(); - } -} diff --git a/app/Http/Controllers/Client/Servers/AddressController.php b/app/Http/Controllers/Client/Servers/AddressController.php new file mode 100644 index 00000000000..2e10905109a --- /dev/null +++ b/app/Http/Controllers/Client/Servers/AddressController.php @@ -0,0 +1,17 @@ +addresses()->with('addressBlock')->get(); + + return IpamAddressData::collect($addresses, DataCollection::class); + } +} diff --git a/app/Http/Controllers/Client/Servers/AuditLogController.php b/app/Http/Controllers/Client/Servers/AuditLogController.php new file mode 100644 index 00000000000..39bb6196c1b --- /dev/null +++ b/app/Http/Controllers/Client/Servers/AuditLogController.php @@ -0,0 +1,40 @@ +auditLogs()) + // Eager loaded so a page of entries does not issue a query per row for the actor and + // the thing acted on. + ->with(['actor', 'subject']) + ->allowedFilters(['event', 'batch']) + ->defaultSort('-created_at') + ->allowedSorts(['created_at']); + + if (! $request->user()?->root_admin) { + $query->clientVisible(); + } + + $logs = $query + ->paginate(min($request->integer('per_page', 25), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($logs, AuditLogData::class); + } +} diff --git a/app/Http/Controllers/Client/Servers/BackupController.php b/app/Http/Controllers/Client/Servers/BackupController.php index a295246c176..c3e16005e98 100644 --- a/app/Http/Controllers/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Client/Servers/BackupController.php @@ -1,73 +1,99 @@ where('backups.server_id', $server->id) - ->allowedFilters(['name']) - ->defaultSort('-created_at') - ->allowedSorts('created_at', 'completed_at') - ->paginate(min($request->query('per_page') ?? 20, 50)); + ->where('backups.server_id', $server->id) + ->allowedFilters(['name']) + ->defaultSort('-created_at') + ->allowedSorts('created_at', 'completed_at') + ->paginate(min($request->query('per_page') ?? 20, 50)); - return fractal($backups, new BackupTransformer())->addMeta([ - 'backup_count' => $this->backupRepository->getNonFailedBackups($server)->count(), - ])->respond(); + // Both quota figures span every non-failed backup, not just the current + // page, so they are aggregated separately from the paginator. + return [ + ...PaginationMeta::paginate($backups, BackupEloquentData::class), + 'backupCount' => $server->backups()->nonFailed()->count(), + 'backupSize' => $server->nonFailedBackupSize(), + ]; } public function store(StoreBackupRequest $request, Server $server) { $backup = $this->backupCreationService ->create( - server : $server, - name : $request->name, - mode : $request->enum('mode', BackupMode::class), + server: $server, + name: $request->name, + mode: $request->enum('mode', BackupMode::class), compressionType: $request->enum('compression_type', BackupCompressionType::class), - isLocked : $request->input('locked', false), + isLocked: $request->boolean('is_locked'), ); - return fractal($backup, new BackupTransformer())->respond(); + // Subject is the server, not the backup: the feed people read is the server's, and a + // backup that is later deleted would take its own history with it. + Audit::record( + AuditEvent::SERVER_BACKUP_CREATED, + subject: $server, + properties: [ + 'backup' => $backup->name, + 'backup_uuid' => $backup->uuid, + 'mode' => $backup->mode, + 'is_locked' => $backup->is_locked, + ], + ); + + return BackupEloquentData::from($backup); } public function restore(RestoreBackupRequest $request, Server $server, Backup $backup) { $this->restoreFromBackupService->handle($server, $backup); - return $this->returnNoContent(); + Audit::record( + AuditEvent::SERVER_BACKUP_RESTORED, + subject: $server, + properties: ['backup' => $backup->name, 'backup_uuid' => $backup->uuid], + ); + + return response()->noContent(); } public function destroy(DeleteBackupRequest $request, Server $server, Backup $backup) { + // Read before the delete: afterwards the model's attributes are all that is left of it. + $properties = ['backup' => $backup->name, 'backup_uuid' => $backup->uuid]; + $this->backupDeletionService->handle($backup); - return $this->returnNoContent(); + Audit::record(AuditEvent::SERVER_BACKUP_DELETED, subject: $server, properties: $properties); + + return response()->noContent(); } } diff --git a/app/Http/Controllers/Client/Servers/FirewallController.php b/app/Http/Controllers/Client/Servers/FirewallController.php new file mode 100644 index 00000000000..e310c887da2 --- /dev/null +++ b/app/Http/Controllers/Client/Servers/FirewallController.php @@ -0,0 +1,193 @@ +firewallService->getOptions($server); + } + + public function updateOptions(UpdateFirewallOptionsRequest $request, Server $server) + { + $inboundPolicy = $request->enum('inbound_policy', FirewallPolicy::class); + $outboundPolicy = $request->enum('outbound_policy', FirewallPolicy::class); + + $options = $this->firewallService->updateOptions( + $server, + $inboundPolicy, + $outboundPolicy, + $request->enum('inbound_log_level', FirewallLogLevel::class), + $request->enum('outbound_log_level', FirewallLogLevel::class), + $request->validated('digest'), + ); + + Audit::record( + AuditEvent::SERVER_FIREWALL_OPTIONS_UPDATED, + subject: $server, + properties: [ + 'inbound_policy' => $inboundPolicy?->value, + 'outbound_policy' => $outboundPolicy?->value, + ], + ); + + return $options; + } + + public function index(Server $server) + { + return FirewallRuleData::collect( + $this->firewallService->getRules($server), + DataCollection::class, + ); + } + + public function store(StoreFirewallRuleRequest $request, Server $server) + { + $rule = $request->toRuleData(); + + $this->firewallService->createRule( + $server, + $rule, + $request->validated('position'), + ); + + Audit::record( + AuditEvent::SERVER_FIREWALL_RULE_CREATED, + subject: $server, + properties: self::ruleProperties($rule), + ); + + return response()->noContent(); + } + + public function update(UpdateFirewallRuleRequest $request, Server $server, int $position) + { + $rule = $request->toRuleData(); + + $this->firewallService->updateRule($server, $position, $rule, $rule->digest); + + Audit::record( + AuditEvent::SERVER_FIREWALL_RULE_UPDATED, + subject: $server, + properties: ['position' => $position] + self::ruleProperties($rule), + ); + + return response()->noContent(); + } + + public function move(MoveFirewallRuleRequest $request, Server $server, int $position) + { + $this->firewallService->moveRule( + $server, + $position, + $request->validated('position'), + $request->validated('digest'), + ); + + Audit::record( + AuditEvent::SERVER_FIREWALL_RULE_MOVED, + subject: $server, + properties: [ + 'from' => $position, + 'to' => $request->validated('position'), + ], + ); + + return response()->noContent(); + } + + public function destroy(DeleteFirewallRuleRequest $request, Server $server, int $position) + { + $this->firewallService->deleteRule($server, $position, $request->validated('digest')); + + // Only the position: rules live in Proxmox, not here, so there is no stored rule left to + // describe once it is gone. + Audit::record( + AuditEvent::SERVER_FIREWALL_RULE_DELETED, + subject: $server, + properties: ['position' => $position], + ); + + return response()->noContent(); + } + + /** + * The parts of a rule worth keeping in the log — enough to see what was opened or closed, + * without copying the whole payload in. + */ + private static function ruleProperties(FirewallRuleData $rule): array + { + return array_filter([ + 'direction' => $rule->direction->value, + 'action' => $rule->action->value, + 'protocol' => $rule->protocol, + 'macro' => $rule->macro, + 'source_address' => $rule->sourceAddress, + 'destination_address' => $rule->destinationAddress, + 'source_port' => $rule->sourcePort, + 'destination_port' => $rule->destinationPort, + 'is_enabled' => $rule->isEnabled, + 'comment' => $rule->comment, + ], fn ($value) => $value !== null && $value !== ''); + } + + public function refs(Server $server) + { + return FirewallRefData::collect( + $this->firewallService->getRefs($server), + DataCollection::class, + ); + } + + public function macros(Server $server) + { + return FirewallMacroData::collect( + $this->firewallService->getMacros($server), + DataCollection::class, + ); + } + + public function log(Request $request, Server $server) + { + return FirewallLogEntryData::collect( + $this->firewallService->getLog( + $server, + max((int) $request->query('start', 0), 0), + min(max((int) $request->query('limit', 100), 1), 500), + ), + DataCollection::class, + ); + } +} diff --git a/app/Http/Controllers/Client/Servers/ResourceController.php b/app/Http/Controllers/Client/Servers/ResourceController.php new file mode 100644 index 00000000000..1b1afbf5b08 --- /dev/null +++ b/app/Http/Controllers/Client/Servers/ResourceController.php @@ -0,0 +1,23 @@ +resourceService->getStorageUsage($server); + + return response()->json([ + 'data' => $usage, + ]); + } +} diff --git a/app/Http/Controllers/Client/Servers/ServerController.php b/app/Http/Controllers/Client/Servers/ServerController.php index 331914ccea4..bb40367c72b 100644 --- a/app/Http/Controllers/Client/Servers/ServerController.php +++ b/app/Http/Controllers/Client/Servers/ServerController.php @@ -1,90 +1,140 @@ ownedBy($request->user())) + ->allowedFilters(['name']) + ->paginate(min($request->query('per_page', 50), 100)) + ->appends($request->query()); + + return PaginationMeta::paginate($servers, ServerData::class); } - public function index(Server $server) + public function show(Server $server) { - return fractal($server, new ServerTransformer())->respond(); + return ServerData::from($server); } - public function details(Server $server) + public function getDeployment(Server $server) { - return fractal( - $this->detailService->getByProxmox($server), new ServerDetailTransformer(), - )->respond(); + $query = $server->deployments()->latest('requested_at'); + + if ($server->lifecycle === ServerLifecycle::INSTALL_FAILED) { + $query->where('status', DeploymentStatus::FAILED); + } + + // Deliberately no `nonCompleted()` filter on the running branch. A + // deployment's terminal status and the server lifecycle it implies are + // written in one transaction (ManagesDeploymentLifecycle::onComplete), + // so scoping this to in-flight deployments meant the completed one was + // never servable: the last poll before the commit still showed a step + // running, and every poll after it 204'd. The progress screen could + // therefore never show the finish — the one moment worth watching — and + // instead emptied itself out while it waited to be replaced. The only + // caller is that screen, and it renders solely for a server whose + // lifecycle is transient, so "the latest deployment" is what it wants. + + $deployment = $query->with(['template', 'steps'])->first(); + + if (! $deployment) { + return response()->noContent(); + } + + return DeploymentData::from($deployment)->include('template', 'steps'); + } + + public function retryInstallation(RetryInstallationRequest $request, Server $server) + { + $server->update([ + 'lifecycle' => ServerLifecycle::DEFERRED_OS_SELECTION, + ]); + + Audit::record(AuditEvent::SERVER_INSTALLATION_RETRIED, subject: $server); + + return response()->noContent(); } public function getState(Server $server) { - return fractal()->item( - $this->serverRepository->setServer($server)->getState(), new ServerStateTransformer(), - )->respond(); + $state = $this->serverClient->setServer($server)->getState(); + $state->pendingPowerAction = $this->powerLock->resolve($server); + $state->lastPowerAction = $this->powerLock->result($server); + + return $state; } - public function updateState(Server $server, SendPowerCommandRequest $request) + public function sendPowerCommand(Server $server, SendPowerCommandRequest $request) { - $this->powerRepository->setServer($server) - ->send($request->enum('state', PowerAction::class)); + $command = $request->enum('command', PowerCommand::class); + + $this->powerCommand->handle($server, $command); - return $this->returnNoContent(); + // Records the request, not the outcome: the command is dispatched asynchronously, and + // whether it landed is deployment/task tracking's job. See docs/audit-log-plan.md. + Audit::record( + AuditEvent::SERVER_POWER_SENT, + subject: $server, + properties: ['command' => $command->value], + ); + + return response()->noContent(); } public function createConsoleSession(CreateConsoleSessionRequest $request, Server $server) { - $server->node->loadMissing('coterm'); - - if ($coterm = $server->node->coterm) { - return new JsonResponse([ - 'data' => [ - 'is_tls_enabled' => $coterm->is_tls_enabled, - 'fqdn' => $coterm->fqdn, - 'port' => $coterm->port, - 'token' => $this->cotermJWTService->handle( - $server, $request->user(), $request->enum('type', ConsoleType::class), - ) - ->toString(), - ], - ]); - } else { - $data = $this->consoleService->createConsoleUserCredentials($server); - - return fractal()->item([ - 'ticket' => $data->ticket, - 'node' => $server->node->cluster, - 'vmid' => $server->vmid, - 'fqdn' => $server->node->fqdn, - 'port' => $server->node->port, - ], new ServerTerminalTransformer())->respond(); - } + // The node is the agent now; only the relay it routes through is a + // separate record to load. + $server->node->loadMissing('relay'); + + $type = $request->enum('type', ConsoleType::class); + + $session = $this->anchorSession->create( + server: $server, + user: $request->user(), + type: $type, + ); + + // Console access is the one client action that hands out an interactive shell, so it is + // worth a line in the log even though it changes nothing. + Audit::record( + AuditEvent::SERVER_CONSOLE_SESSION_CREATED, + subject: $server, + properties: ['type' => $type->value], + ); + + return $session; } } diff --git a/app/Http/Controllers/Client/Servers/SettingsController.php b/app/Http/Controllers/Client/Servers/SettingsController.php index a38bb51fa04..e122ab59475 100644 --- a/app/Http/Controllers/Client/Servers/SettingsController.php +++ b/app/Http/Controllers/Client/Servers/SettingsController.php @@ -1,213 +1,297 @@ connection->transaction(function () use ($server, $request) { - $this->cloudinitService->updateHostname($server, $request->hostname); + $this->cloudinitService->setHostname($server, $request->hostname); $server->update($request->validated()); }); - return fractal($server, new RenamedServerTransformer())->respond(); + Audit::record( + AuditEvent::SERVER_RENAMED, + subject: $server, + properties: ['hostname' => $request->hostname], + ); + + return RenamedServerData::from($server); } - public function getTemplateGroups(Request $request, Server $server) + public function getImageGroups(Request $request, Server $server) { - $templateGroups = QueryBuilder::for(TemplateGroup::query()) - ->defaultSort('order_column') - ->allowedFilters(['name']); + $isAdmin = $request->user()->root_admin; - if (!$request->user()->root_admin) { - $templateGroups = $templateGroups->where( - [['template_groups.hidden', '=', false], ['template_groups.node_id', '=', $server->node->id]], - ) - ->with(['templates' => function ($query) { - $query->where('hidden', '=', false)->orderBy( - 'order_column', - ); - }])->get(); - } else { - $templateGroups = $templateGroups->where( - 'template_groups.node_id', '=', $server->node->id, - ) - ->with(['templates' => function ($query) { - $query->orderBy('order_column'); - }])->get(); + $groups = QueryBuilder::for(ImageGroup::query()) + ->allowedFilters(['name']); + + if (! $isAdmin) { + $groups->where('is_admin_only', false); } - return fractal($templateGroups, new TemplateGroupTransformer())->respond(); + $groups = $groups->with(['definitions' => function ($query) use ($isAdmin) { + if (! $isAdmin) { + $query->where('is_admin_only', false); + } + + // An image with no published version cannot be installed, so + // offering it would only produce a validation error later. + $query->whereHas('versions', fn ($versions) => $versions->where('is_active', true)) + ->with('versions'); + }])->get(); + + return ImageGroupData::collect($groups, DataCollection::class) + ->include('definitions'); } public function reinstall(ReinstallServerRequest $request, Server $server) { $this->connection->transaction(function () use ($server, $request) { - $server->update(['status' => Status::INSTALLING->value]); + $image = ImageDefinition::where('uuid', '=', $request->image_uuid)->firstOrFail(); - $deployment = ServerDeploymentData::from([ - 'server' => $server, - 'template' => Template::where('uuid', '=', $request->template_uuid)->firstOrFail(), - 'account_password' => $request->account_password, - 'should_create_server' => true, + $deployment = $server->deployments()->create([ + 'image_definition_id' => $image->id, + 'image_version_id' => $image->latestVersion()?->id, + 'type' => DeploymentType::REINSTALL, + 'status' => DeploymentStatus::PENDING, 'start_on_completion' => $request->boolean('start_on_completion'), + 'requested_at' => now(), ]); - $this->buildDispatchService->rebuild($deployment); + $this->rebuildServerAction->execute($deployment, $request->account_password); + + // Inside the transaction: a reinstall that rolls back must not leave a record + // claiming it happened. The account password is deliberately not recorded. + Audit::record( + AuditEvent::SERVER_REINSTALLED, + subject: $server, + properties: [ + 'image' => $image->name, + 'image_uuid' => $image->uuid, + 'start_on_completion' => $request->boolean('start_on_completion'), + ], + ); }); - return $this->returnNoContent(); + return response()->noContent(); } - public function getBootOrder(Server $server) + public function getStorage(Server $server) { - $availableDevices = $this->allocationService->getDisks($server); - $configuredDevices = $this->allocationService->getBootOrder($server); - $unconfiguredDevices = []; - - foreach ($availableDevices as $device) { - if ($configuredDevices->where('interface', '=', $device->interface)->first() === null) { - array_push($unconfiguredDevices, $device); - } - } - - return fractal()->item([ - 'unused_devices' => collect($unconfiguredDevices), - 'boot_order' => $configuredDevices, - ], new ServerBootOrderTransformer())->respond(); + // Both halves come out of one config read. Asking the service for disks + // and boot order separately would issue the same PVE request twice. + $config = $this->allocationService->getConfig($server); + + return new ServerStorageData( + devices: $config->disks + ->values() + ->map(fn (DiskData $disk) => StorageDeviceData::fromDisk($disk)), + bootOrder: $config->bootOrder + ->map(fn (DiskData $disk) => $disk->interface->value) + ->values() + ->all(), + ); } public function updateBootOrder(UpdateBootOrderRequest $request, Server $server) { $this->allocationService->setBootOrder($server, $request->order); - return $this->returnNoContent(); + Audit::record( + AuditEvent::SERVER_BOOT_ORDER_UPDATED, + subject: $server, + properties: ['order' => $request->order], + ); + + return response()->noContent(); + } + + public function getSerialConsole(Server $server) + { + return $this->serialConsoleService->status($server); + } + + public function enableSerialConsole(Server $server) + { + $result = $this->serialConsoleService->enable($server); + + Audit::record(AuditEvent::SERVER_CONSOLE_SERIAL_ENABLED, subject: $server); + + return $result; + } + + public function getDisplayConsole(Server $server) + { + return $this->displayConsoleService->status($server); + } + + public function enableDisplayConsole(Server $server) + { + $result = $this->displayConsoleService->enable($server); + + Audit::record(AuditEvent::SERVER_CONSOLE_DISPLAY_ENABLED, subject: $server); + + return $result; } public function getMedia(Request $request, Server $server) { $disks = $this->allocationService->getDisks($server); - if ($request->user()->root_admin) { - $media = $server->isos()->where('is_successful', '=', true)->get()->toArray(); - } else { - $media = $server->isos()->where( - [['hidden', '=', false], ['is_successful', '=', true]], - )->get()->toArray(); - } - $media = array_map(function ($iso) use ($disks) { - if ($disks->where('media_name', '=', $iso['name'])->first()) { - return [ - 'mounted' => true, - ...$iso, - ]; - } else { - return [ - 'mounted' => false, - ...$iso, - ]; - } - }, $media); + // Every ISO in the library is offerable on every node: whether this + // node happens to hold the file yet is settled at mount time, not here. + $query = ISO::query(); + + if (! $request->user()->root_admin) { + $query->where('hidden', '=', false); + } - return fractal($media, new MediaTransformer())->respond(); + return $query->get()->map(fn (ISO $iso) => [ + 'uuid' => $iso->uuid, + 'name' => $iso->name, + 'size' => $iso->size, + 'hidden' => $iso->hidden, + // Matched on the backing volume, the same way mount and unmount + // locate it. The previous check compared a `media_name` property + // DiskData has never had, so every ISO reported itself unmounted. + 'mounted' => $this->allocationService->findMountedISODisk($disks, $iso, $server->node) !== null, + ])->all(); } /* - * Neither of these compares $iso->node_id to $server->node_id, and neither - * does AllocationService beneath them — it pairs the ISO's file name with - * the *server's* node storage. What keeps an ISO from another node out is - * the scoped route-model binding on the /api/client group, which resolves - * {iso} through Server::isos() and 404s anything else. That boundary is - * invisible from here, so: don't hang ->withoutScopedBindings() off these - * routes, and see RouteScopingTest, which fails if anyone does. + * {iso} is resolved globally by uuid here, not through {server}, and that + * is the design rather than an oversight: the library is panel-wide, so + * every ISO is offerable on every node and there is no node_id left to + * scope against. The gate that does apply is visibility, and MediaRequest + * applies it to both of these. Their opt-out from scoped route-model + * binding is recorded in RouteScopingTest. */ - public function mountMedia(MountMediaRequest $request, Server $server, ISO $iso) + public function mountMedia(MediaRequest $request, Server $server, ISO $iso) { - $this->allocationService->mountIso($server, $iso); + // The node may never have seen this ISO. Fetching it is part of + // mounting rather than something an admin has to arrange in advance. + $this->allocationService->mountISO($server, $iso); - return $this->returnNoContent(); + Audit::record( + AuditEvent::SERVER_MEDIA_MOUNTED, + subject: $server, + properties: ['iso' => $iso->name, 'iso_uuid' => $iso->uuid], + ); + + return response()->noContent(); } - public function unmountMedia(Server $server, ISO $iso) + public function unmountMedia(MediaRequest $request, Server $server, ISO $iso) { - $this->allocationService->unmountIso($server, $iso); + $this->allocationService->unmountISO($server, $iso); + + Audit::record( + AuditEvent::SERVER_MEDIA_UNMOUNTED, + subject: $server, + properties: ['iso' => $iso->name, 'iso_uuid' => $iso->uuid], + ); - return $this->returnNoContent(); + return response()->noContent(); } public function getNetworkSettings(Server $server) { - return fractal()->item([ - 'nameservers' => $this->cloudinitService->getNameservers($server), - ], new ServerNetworkTransformer())->respond(); + return new ServerNetworkSettingsData( + nameservers: $this->cloudinitService->getNameservers($server), + ); } public function updateNetworkSettings(UpdateNetworkRequest $request, Server $server) { - $this->cloudinitService->updateNameservers($server, $request->nameservers); + $this->cloudinitService->setNameservers($server, $request->nameservers); - return fractal()->item([ - 'nameservers' => $this->cloudinitService->getNameservers($server), - ], new ServerNetworkTransformer())->respond(); + Audit::record( + AuditEvent::SERVER_NETWORK_SETTINGS_UPDATED, + subject: $server, + properties: ['nameservers' => $request->nameservers], + ); + + return new ServerNetworkSettingsData( + nameservers: $this->cloudinitService->getNameservers($server), + ); } public function getAuthSettings(Server $server) { - return fractal()->item([ - 'ssh_keys' => $this->authService->getSSHKeys($server), - ], new ServerSecurityTransformer())->respond(); + return new ServerSecuritySettingsData( + sshKeys: $this->authService->getSSHKeys($server), + ); } public function updateAuthSettings(UpdateAuthSettingsRequest $request, Server $server) { - if (AuthenticationType::from($request->type) === AuthenticationType::KEY) { - $this->authService->updateSSHKeys($server, $request->ssh_keys); + $type = AuthenticationType::from($request->type); + + if ($type === AuthenticationType::KEY) { + $this->authService->setSSHKeys($server, $request->ssh_keys); } else { - $this->authService->updatePassword($server, $request->password); + $this->authService->setPassword($server, $request->password); } - return $this->returnNoContent(); + // The type and, for keys, how many were set — never the password or the key material. + Audit::record( + AuditEvent::SERVER_AUTH_SETTINGS_UPDATED, + subject: $server, + properties: array_filter([ + 'type' => $type->value, + 'ssh_key_count' => $type === AuthenticationType::KEY + ? count($request->ssh_keys ?? []) + : null, + ], fn ($value) => $value !== null), + ); + + return response()->noContent(); } } diff --git a/app/Http/Controllers/Client/Servers/StatisticController.php b/app/Http/Controllers/Client/Servers/StatisticController.php new file mode 100644 index 00000000000..90d6549fa4b --- /dev/null +++ b/app/Http/Controllers/Client/Servers/StatisticController.php @@ -0,0 +1,44 @@ +enum('from', StatisticTimeRange::class); + $consolidator = $request->enum( + 'consolidator', + StatisticConsolidatorFunction::class, + ) ?? StatisticConsolidatorFunction::AVERAGE; + + $timepoints = $this->statisticsClient->setServer($server)->getStatistics( + $from, + $consolidator, + ); + + /* + * Wrap at the boundary, like every sibling controller does. + * + * `getStatistics()` returns a plain array because its other caller + * (ServerUsagesSyncService) wants one. A plain array is not Responsable, + * so returning it straight from here skipped laravel-data's `wrap` + * config and put a bare JSON array on the wire -- while every other + * client endpoint sends `{"data": [...]}`. The frontend reads + * `{ data }` off every response, got `undefined` here, and threw on + * `.map`, which surfaced as "the node did not return statistics" for a + * request that had in fact succeeded. + */ + return ServerTimepointData::collect($timepoints, DataCollection::class); + } +} diff --git a/app/Http/Controllers/Client/SessionController.php b/app/Http/Controllers/Client/SessionController.php new file mode 100644 index 00000000000..0d164f9e801 --- /dev/null +++ b/app/Http/Controllers/Client/SessionController.php @@ -0,0 +1,19 @@ +user(); + + // The account screen renders straight off this payload, so the policy rides along with it + // rather than costing the client a second request before it can decide what to show. + return UserData::forSelf($user, $policy->for($user)); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index aac515fbac9..2e8af07a455 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -1,12 +1,5 @@ enum('type', ConsoleType::class); - - if ($consoleType === ConsoleType::NOVNC) { - $credentials = $this->consoleService->createNoVncCredentials($server); - - return fractal()->item([ - 'server' => $server, - 'credentials' => $credentials, - ], new NoVncCredentialsTransformer())->respond(); - } else if ($consoleType === ConsoleType::XTERMJS) { - $credentials = $this->consoleService->createXTermjsCredentials($server); - - return fractal()->item([ - 'server' => $server, - 'credentials' => $credentials, - ], new XTermCredentialsTransformer())->respond(); - } - } -} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php deleted file mode 100644 index 7e3bfcb0834..00000000000 --- a/app/Http/Kernel.php +++ /dev/null @@ -1,89 +0,0 @@ - - */ - protected $middleware = [ - // \Convoy\Http\Middleware\TrustHosts::class, - TrustProxies::class, - HandleCors::class, - PreventRequestsDuringMaintenance::class, - ValidatePostSize::class, - TrimStrings::class, - ConvertEmptyStringsToNull::class, - ]; - - /** - * The application's route middleware groups. - * - * @var array> - */ - protected $middlewareGroups = [ - 'web' => [ - EncryptCookies::class, - AddQueuedCookiesToResponse::class, - StartSession::class, - ShareErrorsFromSession::class, - VerifyCsrfToken::class, - SubstituteBindings::class, - ], - - 'api' => [ - // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, - // \Illuminate\Routing\Middleware\ThrottleRequests::class . ':api', - SubstituteBindings::class, - ], - ]; - - /** - * The application's middleware aliases. - * - * Aliases may be used to conveniently assign middleware to routes and groups. - * - * @var array - */ - protected $middlewareAliases = [ - 'auth' => Authenticate::class, - 'auth.basic' => AuthenticateWithBasicAuth::class, - 'auth.session' => AuthenticateSession::class, - 'cache.headers' => SetCacheHeaders::class, - 'can' => Authorize::class, - 'guest' => RedirectIfAuthenticated::class, - 'password.confirm' => RequirePassword::class, - 'signed' => ValidateSignature::class, - 'throttle' => ThrottleRequests::class, - 'verified' => EnsureEmailIsVerified::class, - ]; -} diff --git a/app/Http/Middleware/Activity/AccountSubject.php b/app/Http/Middleware/Activity/AccountSubject.php deleted file mode 100644 index 3e8e557f574..00000000000 --- a/app/Http/Middleware/Activity/AccountSubject.php +++ /dev/null @@ -1,23 +0,0 @@ -user()); - LogTarget::setSubject($request->user()); - - return $next($request); - } -} diff --git a/app/Http/Middleware/Activity/ServerSubject.php b/app/Http/Middleware/Activity/ServerSubject.php deleted file mode 100644 index cceb80485a9..00000000000 --- a/app/Http/Middleware/Activity/ServerSubject.php +++ /dev/null @@ -1,31 +0,0 @@ -route()->parameter('server'); - if ($server instanceof Server) { - LogTarget::setActor($request->user()); - LogTarget::setSubject($server); - } - - return $next($request); - } -} diff --git a/app/Http/Middleware/Admin/Server/ValidateServerLifecycleMiddleware.php b/app/Http/Middleware/Admin/Server/ValidateServerLifecycleMiddleware.php new file mode 100644 index 00000000000..3c496e040ea --- /dev/null +++ b/app/Http/Middleware/Admin/Server/ValidateServerLifecycleMiddleware.php @@ -0,0 +1,29 @@ +route()->parameter('server'); + + if (! $server instanceof Server) { + throw new NotFoundHttpException('Server not found'); + } + + if ($server->lifecycle === ServerLifecycle::DELETING || $server->lifecycle === ServerLifecycle::DELETION_FAILED) { + throw new ServerUnavailableException($server); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/Admin/Server/ValidateServerStatusMiddleware.php b/app/Http/Middleware/Admin/Server/ValidateServerStatusMiddleware.php deleted file mode 100644 index e74986cceda..00000000000 --- a/app/Http/Middleware/Admin/Server/ValidateServerStatusMiddleware.php +++ /dev/null @@ -1,29 +0,0 @@ -route()->parameter('server'); - - if (! $server instanceof Server) { - throw new NotFoundHttpException('Server not found'); - } - - if ($server->status === Status::DELETING->value || $server->status === Status::DELETION_FAILED->value) { - throw new ServerStatusConflictException($server); - } - - return $next($request); - } -} diff --git a/app/Http/Middleware/AdminAuthenticate.php b/app/Http/Middleware/AdminAuthenticate.php index f004ea31757..8105a919db6 100644 --- a/app/Http/Middleware/AdminAuthenticate.php +++ b/app/Http/Middleware/AdminAuthenticate.php @@ -1,7 +1,9 @@ user() || ! $request->user()->root_admin) { - throw new AccessDeniedHttpException(); + // Sanctum resolves an application token to its tokenable, which for panel-wide tokens is the + // SystemActor — not the User that the app's typed user() implies. + /** @var User|SystemActor|null $actor */ + $actor = $request->user(); + + if ($actor instanceof SystemActor) { + return $next($request); + } + + if (! $actor || ! $actor->root_admin) { + throw new AccessDeniedHttpException; } return $next($request); diff --git a/app/Http/Middleware/AnchorAuthenticate.php b/app/Http/Middleware/AnchorAuthenticate.php new file mode 100644 index 00000000000..947bc99743d --- /dev/null +++ b/app/Http/Middleware/AnchorAuthenticate.php @@ -0,0 +1,27 @@ +identity->resolve($request->bearerToken()); + + if ($installation === null) { + throw new HttpException(401, 'Invalid Anchor credentials.', null, [ + 'WWW-Authenticate' => 'Bearer', + ]); + } + + $request->attributes->set('anchor', $installation); + + return $next($request); + } +} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php deleted file mode 100644 index 03586133e01..00000000000 --- a/app/Http/Middleware/Authenticate.php +++ /dev/null @@ -1,19 +0,0 @@ -expectsJson()) { - return route('login'); - } - } -} diff --git a/app/Http/Middleware/Client/Server/AuthenticateServerAccess.php b/app/Http/Middleware/Client/Server/AuthenticateServerAccess.php index 5a35d92af26..ea5725f9e56 100644 --- a/app/Http/Middleware/Client/Server/AuthenticateServerAccess.php +++ b/app/Http/Middleware/Client/Server/AuthenticateServerAccess.php @@ -1,20 +1,26 @@ validateCurrentState(); - } catch (ServerStatusConflictException $exception) { - if ($request->routeIs('client.servers.show')) { - return $next($request); - } - - throw $exception; + // Both axes, spelled out. Suspension used to be a lifecycle value, so `isReady()` + // alone happened to cover it; now that they are separate columns, dropping either + // check silently opens the API up to one of the two conditions. + if (($server->isSuspended() || ! $server->isReady()) && ! $request->routeIs($this->except)) { + throw new ServerUnavailableException($server); } return $next($request); diff --git a/app/Http/Middleware/Client/Server/ServerInstalled.php b/app/Http/Middleware/Client/Server/ServerInstalled.php index aac9daf5a24..f4e63e23322 100644 --- a/app/Http/Middleware/Client/Server/ServerInstalled.php +++ b/app/Http/Middleware/Client/Server/ServerInstalled.php @@ -1,9 +1,9 @@ route()->parameter('server'); if (! $server instanceof Server) { - throw new NotFoundHttpException('No server resource was located in the request parameters.'); + throw new NotFoundHttpException( + 'No server resource was located in the request parameters.', + ); } if (! $server->isInstalled()) { - throw new HttpException(Response::HTTP_FORBIDDEN, 'Access to this resource is not allowed due to the current installation state.'); + throw new HttpException( + Response::HTTP_FORBIDDEN, + 'Access to this resource is not allowed due to the current installation state.', + ); } return $next($request); diff --git a/app/Http/Middleware/Client/Server/ServerNotInstalled.php b/app/Http/Middleware/Client/Server/ServerNotInstalled.php index 35a8aba0fc3..133645d3f94 100644 --- a/app/Http/Middleware/Client/Server/ServerNotInstalled.php +++ b/app/Http/Middleware/Client/Server/ServerNotInstalled.php @@ -1,9 +1,9 @@ route()->parameter('server'); if (! $server instanceof Server) { - throw new NotFoundHttpException('No server resource was located in the request parameters.'); + throw new NotFoundHttpException( + 'No server resource was located in the request parameters.', + ); } if (! $server->isInstalled()) { - throw new HttpException(Response::HTTP_FORBIDDEN, 'Access to this resource is not allowed due to the current non-installation state.'); + throw new HttpException( + Response::HTTP_FORBIDDEN, + 'Access to this resource is not allowed due to the current non-installation state.', + ); } return $next($request); diff --git a/app/Http/Middleware/Client/Server/SubstituteBindings.php b/app/Http/Middleware/Client/Server/SubstituteBindings.php deleted file mode 100644 index 0ca1a9fc75c..00000000000 --- a/app/Http/Middleware/Client/Server/SubstituteBindings.php +++ /dev/null @@ -1,23 +0,0 @@ -router->substituteBindings('server', function ($value) { - return Server::query()->where(strlen($value) === 8 ? 'uuid_short' : 'uuid', $value)->firstOrFail(); - }); - - return parent::handle($request, $next); - } -} diff --git a/app/Http/Middleware/Coterm/CotermAuthenticate.php b/app/Http/Middleware/Coterm/CotermAuthenticate.php deleted file mode 100644 index 263bb3629f2..00000000000 --- a/app/Http/Middleware/Coterm/CotermAuthenticate.php +++ /dev/null @@ -1,56 +0,0 @@ -route()->getName(), $this->except)) { - return $next($request); - } - - if (is_null($bearer = $request->bearerToken())) { - throw new HttpException( - 401, 'Access to this endpoint must include an Authorization header.', null, - ['WWW-Authenticate' => 'Bearer'], - ); - } - - $parts = explode('|', $bearer); - // Ensure that all the correct parts are provided in the header. - if (count($parts) !== 2 || empty($parts[0]) || empty($parts[1])) { - throw new BadRequestHttpException( - 'The Authorization header provided was not in a valid format.', - ); - } - - try { - $coterm = Coterm::where('token_id', $parts[0])->firstOrFail(); - - if (hash_equals($coterm->token, $parts[1])) { - return $next($request); - } - } catch (ModelNotFoundException) { - // Do nothing, we don't want to expose a node not existing at all. - } - - throw new HttpException(401); - } -} diff --git a/app/Http/Middleware/DenyApiTokenAccess.php b/app/Http/Middleware/DenyApiTokenAccess.php new file mode 100644 index 00000000000..c2f16d7a752 --- /dev/null +++ b/app/Http/Middleware/DenyApiTokenAccess.php @@ -0,0 +1,35 @@ +user()?->currentAccessToken() !== null) { + throw new AccessDeniedHttpException('This endpoint cannot be accessed with an API token.'); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php deleted file mode 100644 index 9012214d711..00000000000 --- a/app/Http/Middleware/EncryptCookies.php +++ /dev/null @@ -1,17 +0,0 @@ - - */ - protected $except = [ - // - ]; -} diff --git a/app/Http/Middleware/EnforceTokenAbilities.php b/app/Http/Middleware/EnforceTokenAbilities.php new file mode 100644 index 00000000000..d15650e6b34 --- /dev/null +++ b/app/Http/Middleware/EnforceTokenAbilities.php @@ -0,0 +1,43 @@ + $vocabulary + */ + public function handle(Request $request, Closure $next, string $vocabulary = TokenAbilities::class): Response + { + $token = $request->user()?->currentAccessToken(); + + if ($token instanceof PersonalAccessToken) { + $required = $vocabulary::requiredFor($request); + + if (! $vocabulary::grants($token->abilities ?? [], $required)) { + throw new AccessDeniedHttpException("This token is missing the required ability: {$required}."); + } + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/EnforceTokenNetworkRestrictions.php b/app/Http/Middleware/EnforceTokenNetworkRestrictions.php new file mode 100644 index 00000000000..d66bb3a2b4f --- /dev/null +++ b/app/Http/Middleware/EnforceTokenNetworkRestrictions.php @@ -0,0 +1,37 @@ +user()?->currentAccessToken(); + + if (! $token instanceof PersonalAccessToken || $token->type !== ApiKeyType::APPLICATION) { + return $next($request); + } + + $allowedNetworks = $token->allowed_networks ?? []; + + if ($allowedNetworks === []) { + return $next($request); + } + + $clientIp = $request->ip(); + + if ($clientIp === null || ! IpUtils::checkIp($clientIp, $allowedNetworks)) { + throw new TokenIpNotAllowedException; + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/ForceJsonResponse.php b/app/Http/Middleware/ForceJsonResponse.php index b6984165bbb..0d8d48dd6c9 100644 --- a/app/Http/Middleware/ForceJsonResponse.php +++ b/app/Http/Middleware/ForceJsonResponse.php @@ -1,19 +1,23 @@ headers->set('Accept', 'application/json'); return $next($request); diff --git a/app/Http/Middleware/PreventRequestsDuringMaintenance.php b/app/Http/Middleware/PreventRequestsDuringMaintenance.php deleted file mode 100644 index a0af8cb7626..00000000000 --- a/app/Http/Middleware/PreventRequestsDuringMaintenance.php +++ /dev/null @@ -1,17 +0,0 @@ - - */ - protected $except = [ - // - ]; -} diff --git a/app/Http/Middleware/RecordSessionActivity.php b/app/Http/Middleware/RecordSessionActivity.php new file mode 100644 index 00000000000..fee9beeab05 --- /dev/null +++ b/app/Http/Middleware/RecordSessionActivity.php @@ -0,0 +1,56 @@ +user(); + + // Skip unauthenticated requests and Sanctum bearer-token callers (the client API accepts + // both; only real web sessions belong in the list). A bearer token is the reliable signal — + // a session request never carries one. + if ($user === null || $request->bearerToken() !== null || ! $request->hasSession()) { + return $response; + } + + $sessionId = $request->session()->getId(); + + $record = SessionRecord::query()->firstOrNew(['session_id' => $sessionId]); + + if ( + $record->exists + && $record->last_active_at->gt(Carbon::now()->subSeconds(self::THROTTLE_SECONDS)) + ) { + return $response; + } + + $record->forceFill([ + 'user_id' => $user->getAuthIdentifier(), + 'ip_address' => $request->ip(), + 'user_agent' => mb_substr((string) $request->userAgent(), 0, 500), + 'last_active_at' => Carbon::now(), + ])->save(); + + return $response; + } +} diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php deleted file mode 100644 index 25fdfb0c746..00000000000 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ /dev/null @@ -1,29 +0,0 @@ -check()) { - return redirect(RouteServiceProvider::HOME); - } - } - - return $next($request); - } -} diff --git a/app/Http/Middleware/RequireIdentityConfirmation.php b/app/Http/Middleware/RequireIdentityConfirmation.php new file mode 100644 index 00000000000..942afbc5c6b --- /dev/null +++ b/app/Http/Middleware/RequireIdentityConfirmation.php @@ -0,0 +1,20 @@ +session())) { + throw new AccessDeniedHttpException('Your identity must be confirmed to access this resource.'); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php deleted file mode 100644 index 0bff561c169..00000000000 --- a/app/Http/Middleware/TrimStrings.php +++ /dev/null @@ -1,19 +0,0 @@ - - */ - protected $except = [ - 'current_password', - 'password', - 'password_confirmation', - ]; -} diff --git a/app/Http/Middleware/TrustHosts.php b/app/Http/Middleware/TrustHosts.php deleted file mode 100644 index a48213a3a2e..00000000000 --- a/app/Http/Middleware/TrustHosts.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ - public function hosts(): array - { - return [ - $this->allSubdomainsOfApplicationUrl(), - ]; - } -} diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php deleted file mode 100644 index 6a1ceebd733..00000000000 --- a/app/Http/Middleware/TrustProxies.php +++ /dev/null @@ -1,28 +0,0 @@ -|string|null - */ - protected $proxies; - - /** - * The headers that should be used to detect proxies. - * - * @var int - */ - protected $headers = - Request::HEADER_X_FORWARDED_FOR | - Request::HEADER_X_FORWARDED_HOST | - Request::HEADER_X_FORWARDED_PORT | - Request::HEADER_X_FORWARDED_PROTO | - Request::HEADER_X_FORWARDED_AWS_ELB; -} diff --git a/app/Http/Middleware/ValidateCsrfToken.php b/app/Http/Middleware/ValidateCsrfToken.php new file mode 100644 index 00000000000..5e7160cc4c0 --- /dev/null +++ b/app/Http/Middleware/ValidateCsrfToken.php @@ -0,0 +1,42 @@ +hasValidBearerToken($request) || parent::inExceptArray($request); + } + + private function hasValidBearerToken(Request $request): bool + { + $bearer = $request->bearerToken(); + + if ($bearer === null) { + return false; + } + + // Existence of a real token is enough to rule out a browser-forged request; an expired + // token is still rejected downstream by the Sanctum guard (401), so skipping CSRF for it + // is harmless. + return PersonalAccessToken::findToken($bearer) !== null; + } +} diff --git a/app/Http/Middleware/ValidateSignature.php b/app/Http/Middleware/ValidateSignature.php deleted file mode 100644 index 4da625ed019..00000000000 --- a/app/Http/Middleware/ValidateSignature.php +++ /dev/null @@ -1,22 +0,0 @@ - - */ - protected $except = [ - // 'fbclid', - // 'utm_campaign', - // 'utm_content', - // 'utm_medium', - // 'utm_source', - // 'utm_term', - ]; -} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php deleted file mode 100644 index fce35f05ea0..00000000000 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ /dev/null @@ -1,17 +0,0 @@ - - */ - protected $except = [ - // - ]; -} diff --git a/app/Http/Requests/Admin/AddressBlockGroups/AddressBlockGroupRequest.php b/app/Http/Requests/Admin/AddressBlockGroups/AddressBlockGroupRequest.php new file mode 100644 index 00000000000..924c644ad4f --- /dev/null +++ b/app/Http/Requests/Admin/AddressBlockGroups/AddressBlockGroupRequest.php @@ -0,0 +1,14 @@ +user()->can('attachNode', $this->route('address_block_group')); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + 'network_interface_id' => 'required|integer|exists:network_interfaces,id', + ]; + } +} diff --git a/app/Http/Requests/Admin/AddressBlockGroups/DetachNodeRequest.php b/app/Http/Requests/Admin/AddressBlockGroups/DetachNodeRequest.php new file mode 100644 index 00000000000..85d5c683b5f --- /dev/null +++ b/app/Http/Requests/Admin/AddressBlockGroups/DetachNodeRequest.php @@ -0,0 +1,29 @@ +user()->can('detachNode', $this->route('address_block_group')); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array|string> + */ + public function rules(): array + { + return [ + // No validation rules needed as the params are in the route + ]; + } +} diff --git a/app/Http/Requests/Admin/AddressBlocks/Concerns/ValidatesBlockGeometry.php b/app/Http/Requests/Admin/AddressBlocks/Concerns/ValidatesBlockGeometry.php new file mode 100644 index 00000000000..edc44900dfe --- /dev/null +++ b/app/Http/Requests/Admin/AddressBlocks/Concerns/ValidatesBlockGeometry.php @@ -0,0 +1,84 @@ +after(function (Validator $validator) use ($version) { + // The per-field rules run first; without numeric prefixes there is nothing to compare. + if ($validator->errors()->hasAny(['prefix_length_from', 'prefix_length_to'])) { + return; + } + + $from = $this->integer('prefix_length_from'); + $to = $this->integer('prefix_length_to'); + $max = $version === AddressVersion::IPv4 ? 32 : 128; + + foreach (['prefix_length_from' => $from, 'prefix_length_to' => $to] as $attribute => $value) { + if ($value > $max) { + $validator->errors()->add( + $attribute, + "The {$attribute} may not be greater than {$max} for an {$version->value} block.", + ); + } + } + + if ($validator->errors()->hasAny(['prefix_length_from', 'prefix_length_to'])) { + return; + } + + if ($to < $from) { + $validator->errors()->add( + 'prefix_length_to', + 'The output prefix length must be at least the source prefix length — a block cannot hand out units larger than itself.', + ); + + return; + } + + $this->validateGatewayLeavesCapacity($validator, $from, $to); + }); + } + + /** + * A block whose gateway sits inside its only allocatable unit has no capacity at all: that unit + * is auto-reserved, so generation produces one locked row and nothing else. Surface it here + * rather than letting an operator discover it after hitting Generate. + */ + private function validateGatewayLeavesCapacity(Validator $validator, int $from, int $to): void + { + /** @var ?string $gateway */ + $gateway = $this->input('gateway'); + + // Both addresses have to be parseable before the containment check means anything. + if (empty($gateway) || $from !== $to || $validator->errors()->hasAny(['base_ip', 'gateway'])) { + return; + } + + // No version to set — the block reads it back off base_ip. + $block = new AddressBlock([ + 'base_ip' => $this->string('base_ip')->toString(), + 'gateway' => $gateway, + 'prefix_length_from' => $from, + 'prefix_length_to' => $to, + ]); + + if ($block->containsAddress($gateway)) { + $validator->errors()->add( + 'gateway', + 'The gateway falls inside the block\'s only allocatable unit, which leaves nothing to allocate. Widen the output prefix length or move the gateway outside this block.', + ); + } + } +} diff --git a/app/Http/Requests/Admin/AddressBlocks/StoreAddressBlockRequest.php b/app/Http/Requests/Admin/AddressBlocks/StoreAddressBlockRequest.php new file mode 100644 index 00000000000..f3170936160 --- /dev/null +++ b/app/Http/Requests/Admin/AddressBlocks/StoreAddressBlockRequest.php @@ -0,0 +1,84 @@ +string('version')->toString()); + + if ($version !== null) { + $this->validateBlockGeometry($validator, $version); + } + } + + protected function prepareForValidation(): void + { + $baseIp = $this->string('base_ip')->toString(); + /** @var ?string $gateway */ + $gateway = $this->input('gateway'); + + $this->merge([ + 'ip' => IPFactory::parseAddressString($baseIp)->toString(), + 'gateway' => $gateway ? IPFactory::parseAddressString($gateway)->toString() : null, + ]); + } + + public function rules(): array + { + $rules = Arr::except(AddressBlock::getRules(), ['address_block_group_id']); + + // The block's version is derived from base_ip and never stored, but it stays a required + // input: it is what the caller *meant* to create, and the rules below reject a base IP or + // gateway of the other family rather than silently building a block of the wrong version. + $rules['version'] = ['required', 'in:ipv4,ipv6']; + + // Override base_ip validation to ensure it matches the version (IPv4 or IPv6) + $rules['base_ip'] = [ + 'required', + function (string $attribute, mixed $value, \Closure $fail) { + $version = request()->input('version'); + + if ($version === 'ipv4' && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $fail('The base IP must be a valid IPv4 address when version is IPv4.'); + } elseif ($version === 'ipv6' && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $fail('The base IP must be a valid IPv6 address when version is IPv6.'); + } elseif (! filter_var($value, FILTER_VALIDATE_IP)) { + $fail('The base IP must be a valid IP address.'); + } + }, + ]; + + $rules['gateway'] = [ + 'nullable', + function (string $attribute, mixed $value, \Closure $fail) { + if (empty($value)) { + return; + } + + $version = request()->input('version'); + + if ($version === 'ipv4' && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $fail('The gateway must be a valid IPv4 address when version is IPv4.'); + } elseif ($version === 'ipv6' && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $fail('The gateway must be a valid IPv6 address when version is IPv6.'); + } elseif (! filter_var($value, FILTER_VALIDATE_IP)) { + $fail('The gateway must be a valid IP address.'); + } + }, + ]; + + return $rules; + } +} diff --git a/app/Http/Requests/Admin/AddressBlocks/UpdateAddressBlockRequest.php b/app/Http/Requests/Admin/AddressBlocks/UpdateAddressBlockRequest.php new file mode 100644 index 00000000000..328a8c41781 --- /dev/null +++ b/app/Http/Requests/Admin/AddressBlocks/UpdateAddressBlockRequest.php @@ -0,0 +1,100 @@ +parameter('address_block', AddressBlock::class); + + // Version is immutable on update, so the block's own value is authoritative. + $this->validateBlockGeometry($validator, $addressBlock->version); + } + + protected function prepareForValidation(): void + { + $baseIp = $this->string('base_ip')->toString(); + /** @var ?string $gateway */ + $gateway = $this->input('gateway'); + + $this->merge([ + 'ip' => IPFactory::parseAddressString($baseIp)->toString(), + 'gateway' => $gateway ? IPFactory::parseAddressString($gateway)->toString() : null, + ]); + } + + public function rules(): array + { + $rules = Arr::except(AddressBlock::getRules(), ['address_block_group_id']); + + // Get the address block from the route + /** @var AddressBlock $addressBlock */ + $addressBlock = $this->parameter('address_block', AddressBlock::class); + + // Check if any addresses are attached to servers + $hasAttachedAddresses = $addressBlock->addresses()->whereNotNull('server_id')->exists(); + + // Add validation for critical fields that can't be changed if IPs are attached to servers + $criticalFieldValidation = function (string $attribute, mixed $value, \Closure $fail) use ($addressBlock, $hasAttachedAddresses) { + // If the value is changing and there are attached addresses, fail validation + if ($value != $addressBlock->{$attribute} && $hasAttachedAddresses) { + $fail("The {$attribute} cannot be changed because some IP addresses are attached to servers."); + } + }; + + // Override base_ip validation to ensure it matches the version (IPv4 or IPv6) + // and can't be changed if IPs are attached to servers + $rules['base_ip'] = [ + 'required', + function (string $attribute, mixed $value, \Closure $fail) use ($addressBlock) { + $version = $addressBlock->version; + + if ($version === AddressVersion::IPv4 && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $fail('The base IP must be a valid IPv4 address when version is IPv4.'); + } elseif ($version === AddressVersion::IPv6 && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $fail('The base IP must be a valid IPv6 address when version is IPv6.'); + } elseif (! filter_var($value, FILTER_VALIDATE_IP)) { + $fail('The base IP must be a valid IP address.'); + } + }, + $criticalFieldValidation, + ]; + + // Add validation for prefix_length_from and prefix_length_to + $rules['prefix_length_from'][] = $criticalFieldValidation; + $rules['prefix_length_to'][] = $criticalFieldValidation; + + $rules['gateway'] = [ + 'nullable', + function (string $attribute, mixed $value, \Closure $fail) use ($addressBlock) { + if (empty($value)) { + return; + } + + $version = $addressBlock->version; + + if ($version === AddressVersion::IPv4 && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + $fail('The gateway must be a valid IPv4 address when version is IPv4.'); + } elseif ($version === AddressVersion::IPv6 && ! filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { + $fail('The gateway must be a valid IPv6 address when version is IPv6.'); + } elseif (! filter_var($value, FILTER_VALIDATE_IP)) { + $fail('The gateway must be a valid IP address.'); + } + }, + ]; + + return $rules; + } +} diff --git a/app/Http/Requests/Admin/AddressPools/Addresses/StoreAddressRequest.php b/app/Http/Requests/Admin/AddressPools/Addresses/StoreAddressRequest.php deleted file mode 100644 index a816984c7e2..00000000000 --- a/app/Http/Requests/Admin/AddressPools/Addresses/StoreAddressRequest.php +++ /dev/null @@ -1,79 +0,0 @@ - 'sometimes|boolean', - 'starting_address' => 'required_if:is_bulk_action,1|exclude_if:is_bulk_action,0|ip', - 'ending_address' => 'required_if:is_bulk_action,1|exclude_if:is_bulk_action,0|ip', - 'address' => 'required_if:is_bulk_action,0|exclude_if:is_bulk_action,1|ip', - ...$rules, - ]; - } - - public function after(): array - { - $rules = []; - - if ($this->boolean('is_bulk_action')) { - $rules[] = new ValidateAddressType( - $this->enum('type', AddressType::class), - ['starting_address', 'ending_address', 'gateway'], - ); - $rules[] = new ValidateAddressRangeSize( - $this->enum('type', AddressType::class), - ); - } - - if (!$this->boolean('is_bulk_action')) { - $pool = $this->parameter('address_pool', AddressPool::class); - $rules[] = new ValidateAddressType( - $this->enum('type', AddressType::class), ['address', 'gateway'], - ); - $rules[] = new ValidateAddressUniqueness($pool->id); - } - - return $rules; - } - - /** - * Transform IPv6 addresses to lowercase to avoid saving duplicate variants that are upper - * and lowercase. - * - * If you don't prefer this lowercase behavior, you can thank Fro! I surveyed him for IPv6 - * capitalization preference. - */ - protected function passedValidation(): void - { - if ($this->boolean('is_bulk_action')) { - $this->replace([ - 'address' => strtolower($this->string('address')), - ]); - } - - if (!is_null($this->mac_address)) { - $this->replace([ - 'mac_address' => strtolower($this->string('mac_address')), - ]); - } - - $this->replace([ - 'gateway' => strtolower($this->string('gateway')), - ]); - } -} diff --git a/app/Http/Requests/Admin/AddressPools/Addresses/UpdateAddressRequest.php b/app/Http/Requests/Admin/AddressPools/Addresses/UpdateAddressRequest.php deleted file mode 100644 index 7289c2e9668..00000000000 --- a/app/Http/Requests/Admin/AddressPools/Addresses/UpdateAddressRequest.php +++ /dev/null @@ -1,33 +0,0 @@ -parameter('address', Address::class)); - - return Arr::except($rules, 'address_pool_id'); - } - - public function after(): array - { - $pool = $this->parameter('address_pool', AddressPool::class); - $address = $this->parameter('address', Address::class); - - return [ - new ValidateAddressType($this->enum('type', AddressType::class), ['address']), - new ValidateAddressUniqueness($pool->id, $address->address), - ]; - } -} diff --git a/app/Http/Requests/Admin/AddressPools/StoreAddressPoolRequest.php b/app/Http/Requests/Admin/AddressPools/StoreAddressPoolRequest.php deleted file mode 100644 index 72eb6c1f860..00000000000 --- a/app/Http/Requests/Admin/AddressPools/StoreAddressPoolRequest.php +++ /dev/null @@ -1,19 +0,0 @@ - 'sometimes|array', - 'node_ids.*' => 'exists:nodes,id|integer', - ]; - } -} diff --git a/app/Http/Requests/Admin/AddressPools/UpdateAddressPoolRequest.php b/app/Http/Requests/Admin/AddressPools/UpdateAddressPoolRequest.php deleted file mode 100644 index 5bd60fb4026..00000000000 --- a/app/Http/Requests/Admin/AddressPools/UpdateAddressPoolRequest.php +++ /dev/null @@ -1,58 +0,0 @@ -parameter('address_pool', AddressPool::class); - - return [ - ...AddressPool::getRulesForUpdate($addressPool), - 'node_ids' => 'sometimes|array', - 'node_ids.*' => 'exists:nodes,id|integer', - ]; - } - - public function after(): array - { - /** @var AddressPool $addressPool */ - $addressPool = $this->parameter('address_pool', AddressPool::class); - - return [ - function (Validator $validator) use ($addressPool) { - /** @var int[] $nodeIdsToSync */ - if ($nodeIdsToSync = $this->node_ids) { - $existingAttachedNodeIds = $addressPool->nodes()->pluck('id'); - - $nodeIdsRemoved = $existingAttachedNodeIds->diff($nodeIdsToSync); - - $isAddressesAllocated = Node::whereIn('nodes.id', $nodeIdsRemoved)->join( - 'servers', - 'nodes.id', - '=', - 'servers.node_id', - ) - ->join('ip_addresses', 'servers.id', '=', 'ip_addresses.server_id') - ->where( - 'ip_addresses.address_pool_id', - '=', - $addressPool->id, - ) - ->exists(); - - if ($isAddressesAllocated) { - $validator->errors()->add('node_ids', 'Cannot detach nodes with servers using addresses from this pool.'); - } - } - }, - ]; - } -} diff --git a/app/Http/Requests/Admin/Addresses/BulkAddressRequest.php b/app/Http/Requests/Admin/Addresses/BulkAddressRequest.php new file mode 100644 index 00000000000..b38a802a0c0 --- /dev/null +++ b/app/Http/Requests/Admin/Addresses/BulkAddressRequest.php @@ -0,0 +1,24 @@ + 'required|string|in:reserve,release,delete', + /* + * Capped at the widest selection the UI can make: the map draws up to MAX_UNITS cells + * and a single drag can take all of them. The first version of this capped at a page + * of the table, which the map then broke on its first drag — the ceiling belongs to + * the largest surface that can select, not the smallest. + */ + 'ids' => 'required|array|min:1|max:'.AddressMapData::MAX_UNITS, + 'ids.*' => 'required|integer', + ]; + } +} diff --git a/app/Http/Requests/Admin/Addresses/UpdateAddressRequest.php b/app/Http/Requests/Admin/Addresses/UpdateAddressRequest.php new file mode 100644 index 00000000000..e08f9e646e5 --- /dev/null +++ b/app/Http/Requests/Admin/Addresses/UpdateAddressRequest.php @@ -0,0 +1,56 @@ + [ + ...Address::getRules()['server_id'], + function (string $attribute, mixed $value, \Closure $fail) { + // check that the address can be assigned to the server + if (! $value) { + return; // No server selected, so no validation needed + } + + $address = $this->parameter('address', Address::class); + + // A reserved address is fully locked — it must be unreserved before it can be + // assigned to a server. + if ($address->state === AddressState::Reserved) { + $fail('This address is reserved. Unreserve it before assigning it to a server.'); + + return; + } + + $server = Server::find($value); + + if (! $server) { + return; // Server doesn't exist, other validation rules will catch this + } + + // Get the address block group for this address + $addressBlockGroup = $address->addressBlock->addressBlockGroup; + + // Check if the server's node has any network interfaces that are associated with this address block group + $nodeHasCompatibleInterface = $server->node->networkInterfaces() + ->whereHas('addressBlockGroups', function ($query) use ($addressBlockGroup) { + $query->where('address_block_groups.id', $addressBlockGroup->id); + }) + ->exists(); + + if (! $nodeHasCompatibleInterface) { + $fail("This address cannot be assigned to the server because the server's node does not have a network interface assigned to the address block group."); + } + }, + ], + ]; + } +} diff --git a/app/Http/Requests/Admin/ApproveAnchorEnrollmentRequest.php b/app/Http/Requests/Admin/ApproveAnchorEnrollmentRequest.php new file mode 100644 index 00000000000..2ad1fddfbff --- /dev/null +++ b/app/Http/Requests/Admin/ApproveAnchorEnrollmentRequest.php @@ -0,0 +1,70 @@ +parameter('anchor_enrollment', AnchorEnrollment::class); + + if ($enrollment->mode === AnchorMode::RELAY) { + return [ + 'name' => ['sometimes', 'string', 'max:191'], + 'public_url' => ['required', 'url:http,https', 'max:2048'], + 'panel_url_override' => ['sometimes', 'nullable', 'url:http,https', 'max:2048'], + ]; + } + + // Array form throughout: `$validationRules` mixes pipe strings with + // arrays, and appending a rule object to a pipe string silently makes + // the whole string one rule name. + $node = Node::getRules(); + + return [ + // Operator policy. Nothing the host reports may supply these. + 'location_id' => $node['location_id'], + 'memory_overallocate' => $node['memory_overallocate'], + 'relay_id' => ['sometimes', 'nullable', 'integer', 'exists:relays,id'], + + // How the panel reaches the host, and how it reaches the agent. + 'fqdn' => [...$node['fqdn'], new Hostname], + 'port' => $node['port'], + 'verify_tls' => ['sometimes', 'boolean'], + 'agent_public_url' => ['required', 'url:http,https', 'max:2048'], + 'agent_panel_url_override' => ['sometimes', 'nullable', 'url:http,https', 'max:2048'], + + /* + * Still typed, and the last thing standing between this screen and + * one field. The agent runs as root on the host and can mint its own + * API token; until it does, the operator pastes one. + */ + 'token_id' => $node['token_id'], + 'token_secret' => $node['token_secret'], + + // Reported by the host and pre-filled; editable because a report is + // evidence, not authority. + 'display_name' => $node['display_name'], + 'name' => $node['name'], + 'socket_count' => $node['socket_count'], + 'core_count' => $node['core_count'], + 'cpu_count' => $node['cpu_count'], + 'memory' => $node['memory'], + ]; + } +} diff --git a/app/Http/Requests/Admin/Coterms/DeleteCotermRequest.php b/app/Http/Requests/Admin/Coterms/DeleteCotermRequest.php deleted file mode 100644 index 27cc37c64e6..00000000000 --- a/app/Http/Requests/Admin/Coterms/DeleteCotermRequest.php +++ /dev/null @@ -1,14 +0,0 @@ -user()->can('delete', $this->parameter('coterm', Coterm::class)); - } -} diff --git a/app/Http/Requests/Admin/Coterms/StoreCotermRequest.php b/app/Http/Requests/Admin/Coterms/StoreCotermRequest.php deleted file mode 100644 index 5c292024698..00000000000 --- a/app/Http/Requests/Admin/Coterms/StoreCotermRequest.php +++ /dev/null @@ -1,23 +0,0 @@ - ['nullable', 'array'], - 'node_ids.*' => ['required', 'integer', 'exists:nodes,id'], - ]; - } -} diff --git a/app/Http/Requests/Admin/Coterms/UpdateAttachedNodesRequest.php b/app/Http/Requests/Admin/Coterms/UpdateAttachedNodesRequest.php deleted file mode 100644 index fe2886651f7..00000000000 --- a/app/Http/Requests/Admin/Coterms/UpdateAttachedNodesRequest.php +++ /dev/null @@ -1,16 +0,0 @@ - 'required|array', - 'nodes_ids.*' => 'required|integer|exists:nodes,id', - ]; - } -} diff --git a/app/Http/Requests/Admin/Coterms/UpdateCotermRequest.php b/app/Http/Requests/Admin/Coterms/UpdateCotermRequest.php deleted file mode 100644 index d1d0e7e95a7..00000000000 --- a/app/Http/Requests/Admin/Coterms/UpdateCotermRequest.php +++ /dev/null @@ -1,22 +0,0 @@ -parameter('coterm', Coterm::class); - $rules = Coterm::getRulesForUpdate($coterm); - - return [ - ...Arr::only($rules, ['name', 'is_tls_enabled', 'fqdn', 'port']), - 'node_ids' => ['nullable', 'array'], - 'node_ids.*' => ['required', 'integer', 'exists:nodes,id'], - ]; - } -} diff --git a/app/Http/Requests/Admin/ISOs/StoreISORequest.php b/app/Http/Requests/Admin/ISOs/StoreISORequest.php new file mode 100644 index 00000000000..8ee3b2bd2bf --- /dev/null +++ b/app/Http/Requests/Admin/ISOs/StoreISORequest.php @@ -0,0 +1,47 @@ + $rules['name'], + 'file_name' => $rules['file_name'], + 'hidden' => $rules['hidden'], + + // A link the operator hosts, or a file they uploaded. Exactly one: + // both answer the same question, so accepting both would only leave + // a question about which one a node was given. + 'url' => ['nullable', 'url', 'max:2048', 'required_without:path', 'prohibits:path'], + 'path' => ['nullable', 'string', 'max:191', 'required_without:url', 'prohibits:url'], + + 'sha256' => ['nullable', 'string', 'size:64', 'regex:/^[a-f0-9]{64}$/i'], + 'size' => 'sometimes|numeric|min:0', + ]; + } + + public function after(): array + { + return [ + function (Validator $validator) { + // The file name is what the ISO is called on every node it ever + // lands on, so two library entries sharing one would fight over + // the same file. + if (ISO::where('file_name', $this->string('file_name'))->exists()) { + $validator->errors()->add( + 'file_name', + __('validation.unique', ['attribute' => 'file name']), + ); + } + }, + ]; + } +} diff --git a/app/Http/Requests/Admin/ISOs/UpdateISORequest.php b/app/Http/Requests/Admin/ISOs/UpdateISORequest.php new file mode 100644 index 00000000000..8c8ce531864 --- /dev/null +++ b/app/Http/Requests/Admin/ISOs/UpdateISORequest.php @@ -0,0 +1,22 @@ +schemaNode())]; + + return $rules; + } + + private function schemaNode(): ?Node + { + return filled($nodeId = $this->input('schema_node_id')) + ? Node::find($nodeId) + : null; + } +} diff --git a/app/Http/Requests/Admin/Images/ImageGroupRequest.php b/app/Http/Requests/Admin/Images/ImageGroupRequest.php new file mode 100644 index 00000000000..c9c96e7faa9 --- /dev/null +++ b/app/Http/Requests/Admin/Images/ImageGroupRequest.php @@ -0,0 +1,20 @@ + 'required|string|max:40', + 'description' => 'nullable|string|max:500', + 'icon' => ['nullable', new Enum(ImageIcon::class)], + 'is_admin_only' => 'required|boolean', + ]; + } +} diff --git a/app/Http/Requests/Admin/Images/ImageVersionRequest.php b/app/Http/Requests/Admin/Images/ImageVersionRequest.php new file mode 100644 index 00000000000..97270964424 --- /dev/null +++ b/app/Http/Requests/Admin/Images/ImageVersionRequest.php @@ -0,0 +1,46 @@ + ['required', 'string', 'max:32', 'regex:/^\d+\.\d+\.\d+$/'], + 'is_active' => 'sometimes|boolean', + + 'disks' => 'required|array|min:1', + 'disks.*.slot' => ['required', 'string', 'regex:/^(?:scsi|ide|sata|virtio|efidisk)\d+$/'], + 'disks.*.role' => ['required', Rule::in(ImageDiskRole::values())], + + // Exactly one source per disk: a link the operator hosts, or a file + // they uploaded. Both are the same thing to a node, so allowing + // both would only leave a question about which one won. + 'disks.*.url' => ['nullable', 'required_without:disks.*.path', 'prohibits:disks.*.path', 'url'], + 'disks.*.path' => ['nullable', 'required_without:disks.*.url', 'string'], + + 'disks.*.sha256' => ['required', 'string', 'regex:/^[a-f0-9]{64}$/i'], + 'disks.*.size' => 'required|integer|min:1', + 'disks.*.virtual_size' => 'required|integer|min:1', + 'disks.*.format' => 'sometimes|string|in:qcow2,raw', + ]; + } + + public function after(): array + { + return [ + function ($validator) { + $roles = collect($this->input('disks', []))->pluck('role'); + + if ($roles->filter(fn ($role) => $role === ImageDiskRole::SYSTEM->value)->count() !== 1) { + $validator->errors()->add('disks', 'A version needs exactly one system disk.'); + } + }, + ]; + } +} diff --git a/app/Http/Requests/Admin/LocationFormRequest.php b/app/Http/Requests/Admin/LocationFormRequest.php index 53ee199ee28..957e3255f7c 100644 --- a/app/Http/Requests/Admin/LocationFormRequest.php +++ b/app/Http/Requests/Admin/LocationFormRequest.php @@ -1,8 +1,8 @@ user()->can('delete', $this->parameter('network_interface', NetworkInterface::class)); + } + + public function rules(): array + { + return [ + // + ]; + } + + public function after(): array + { + return [ + function (Validator $validator) { + /** @var NetworkInterface $networkInterface */ + $networkInterface = $this->parameter('network_interface', NetworkInterface::class); + $nodeId = $networkInterface->node_id; + + $isInUse = $networkInterface->addressBlockGroups() + ->whereHas('addressBlocks.addresses', function ($query) use ($nodeId) { + $query->whereNotNull('server_id') + ->whereHas('server', function ($serverQuery) use ($nodeId) { + $serverQuery->where('node_id', $nodeId); + }); + }) + ->exists(); + + if ($isInUse) { + $validator->errors()->add( + 'network_interface', + 'This network interface cannot be deleted because it is in use by one or more servers.' + ); + } + }, + ]; + } +} diff --git a/app/Http/Requests/Admin/Nodes/Isos/StoreIsoRequest.php b/app/Http/Requests/Admin/Nodes/Isos/StoreIsoRequest.php deleted file mode 100644 index 90b97ac86dd..00000000000 --- a/app/Http/Requests/Admin/Nodes/Isos/StoreIsoRequest.php +++ /dev/null @@ -1,60 +0,0 @@ - 'required|boolean', - 'name' => $isoRules['name'], - 'file_name' => $isoRules['file_name'], - 'hidden' => $isoRules['hidden'], - 'link' => 'required_if:should_download,1|url|max:191|exclude_if:should_download,0', - 'checksum_algorithm' => ['sometimes', new Enum( - ChecksumAlgorithm::class, - ), 'exclude_if:should_download,0'], - 'checksum' => 'required_with:checksum_algorithm|string|max:191|exclude_if:should_download,0', - ]; - - return $rules; - } - - public function after(): array - { - $rules = [ - function (Validator $validator) { - if (ISO::where('file_name', $this->string('file_name'))->exists()) { - $validator->errors()->add( - 'file_name', __('validation.unique', ['attribute' => 'file name']), - ); - } - }, - ]; - - if (!$this->boolean('should_download')) { - $rules[] = function (Validator $validator) { - $node = $this->parameter('node', Node::class); - - $iso = app(IsoService::class)->getIso($node, $this->input('file_name')); - - if (is_null($iso)) { - $validator->errors()->add('file_name', 'This ISO doesn\'t exist.'); - } - }; - } - - return $rules; - } -} diff --git a/app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php b/app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php deleted file mode 100644 index 225859c1b59..00000000000 --- a/app/Http/Requests/Admin/Nodes/Isos/UpdateIsoRequest.php +++ /dev/null @@ -1,20 +0,0 @@ -parameter('iso', ISO::class)); - - return [ - 'name' => $rules['name'], - 'hidden' => $rules['hidden'], - ]; - } - -} diff --git a/app/Http/Requests/Admin/Nodes/NetworkInterfaces/NetworkInterfaceRequest.php b/app/Http/Requests/Admin/Nodes/NetworkInterfaces/NetworkInterfaceRequest.php new file mode 100644 index 00000000000..50b3ffe3391 --- /dev/null +++ b/app/Http/Requests/Admin/Nodes/NetworkInterfaces/NetworkInterfaceRequest.php @@ -0,0 +1,35 @@ +route('network_interface'); + $isVlanAware = $this->has('is_vlan_aware') + ? $this->boolean('is_vlan_aware') + : ($networkInterface instanceof NetworkInterface && $networkInterface->is_vlan_aware); + + if ($this->filled('vlan_tag') && ! $isVlanAware) { + $validator->errors()->add( + 'vlan_tag', + 'The network interface must be marked VLAN-aware before assigning a VLAN tag.', + ); + } + }, + ]; + } +} diff --git a/app/Http/Requests/Admin/Nodes/NetworkInterfaces/VlanRequest.php b/app/Http/Requests/Admin/Nodes/NetworkInterfaces/VlanRequest.php new file mode 100644 index 00000000000..5910a26ebac --- /dev/null +++ b/app/Http/Requests/Admin/Nodes/NetworkInterfaces/VlanRequest.php @@ -0,0 +1,45 @@ +where('network_interface_id', $this->networkInterface()->id) + ->ignore($this->route('vlan')); + + return $rules; + } + + public function after(): array + { + return [ + function (Validator $validator) { + if (! $this->networkInterface()->is_vlan_aware) { + $validator->errors()->add( + 'tag', + 'The network interface must be marked VLAN-aware before declaring VLANs on it.', + ); + } + }, + ]; + } + + private function networkInterface(): NetworkInterface + { + return $this->parameter('network_interface', NetworkInterface::class); + } +} diff --git a/app/Http/Requests/Admin/Nodes/Storages/StorageRequest.php b/app/Http/Requests/Admin/Nodes/Storages/StorageRequest.php new file mode 100644 index 00000000000..f85003f4051 --- /dev/null +++ b/app/Http/Requests/Admin/Nodes/Storages/StorageRequest.php @@ -0,0 +1,37 @@ +parameter('node', Node::class); + + $storageId = null; + + if ($this->isMethod('PUT') || $this->isMethod('PATCH')) { + /** @var Storage $storage */ + $storage = $this->parameter('storage', Storage::class); + // Set the ID to ignore for the uniqueness check + $storageId = $storage->id; + } + $rules['name'][] = new UniqueStorageNamePerNode($node->id, $storageId); + + // Always optional. This used to be required when the operator ticked + // "shareable", but that flag is gone -- whether a storage is shared is + // Proxmox's answer (`pve_shared`), and it is not known at registration + // because nothing has polled the node yet. + $rules['display_name'] = 'nullable|string|max:40'; + + return $rules; + } +} diff --git a/app/Http/Requests/Admin/Nodes/Storages/UpdateBackupOrderRequest.php b/app/Http/Requests/Admin/Nodes/Storages/UpdateBackupOrderRequest.php new file mode 100644 index 00000000000..31c724e3b15 --- /dev/null +++ b/app/Http/Requests/Admin/Nodes/Storages/UpdateBackupOrderRequest.php @@ -0,0 +1,27 @@ + [ + 'required', + 'array', + 'min:1', + ], + 'ids.*' => [ + 'required', + 'integer', + 'exists:storages,id', + new StorageAllows(StorageContentType::BACKUPS), + ], + ]; + } +} diff --git a/app/Http/Requests/Admin/Nodes/StoreNodeRequest.php b/app/Http/Requests/Admin/Nodes/StoreNodeRequest.php deleted file mode 100644 index 16e72034ea1..00000000000 --- a/app/Http/Requests/Admin/Nodes/StoreNodeRequest.php +++ /dev/null @@ -1,19 +0,0 @@ - $rules['name'], - 'hidden' => $rules['hidden'], - ]; - } -} diff --git a/app/Http/Requests/Admin/Nodes/TemplateGroups/UpdateGroupOrderRequest.php b/app/Http/Requests/Admin/Nodes/TemplateGroups/UpdateGroupOrderRequest.php deleted file mode 100644 index e2f5f9be361..00000000000 --- a/app/Http/Requests/Admin/Nodes/TemplateGroups/UpdateGroupOrderRequest.php +++ /dev/null @@ -1,27 +0,0 @@ - 'required|array', - 'order.*' => 'required|integer|exists:template_groups,id', - ]; - } - - public function withValidator(Validator $validator) - { - // validate if each order id is unique in the array - $validator->after(function ($validator) { - if (count($this->order) !== count(array_unique($this->order))) { - $validator->errors()->add('order', 'Duplicate order id'); - } - }); - } -} diff --git a/app/Http/Requests/Admin/Nodes/Templates/TemplateRequest.php b/app/Http/Requests/Admin/Nodes/Templates/TemplateRequest.php deleted file mode 100644 index c70732620c0..00000000000 --- a/app/Http/Requests/Admin/Nodes/Templates/TemplateRequest.php +++ /dev/null @@ -1,33 +0,0 @@ - - */ - public function rules(): array - { - $rules = Template::getRules(); - - return [ - 'name' => $rules['name'], - 'vmid' => $rules['vmid'], - 'hidden' => $rules['hidden'], - ]; - } -} diff --git a/app/Http/Requests/Admin/Nodes/Templates/UpdateTemplateOrderRequest.php b/app/Http/Requests/Admin/Nodes/Templates/UpdateTemplateOrderRequest.php deleted file mode 100644 index 29f921058c2..00000000000 --- a/app/Http/Requests/Admin/Nodes/Templates/UpdateTemplateOrderRequest.php +++ /dev/null @@ -1,32 +0,0 @@ - 'required|array', - 'order.*' => 'required|integer|exists:templates,id', - ]; - } - - public function withValidator(Validator $validator) - { - // validate if each order id is unique in the array - $validator->after(function ($validator) { - if (count($this->order) !== count(array_unique($this->order))) { - $validator->errors()->add('order', 'Duplicate order id'); - } - }); - } -} diff --git a/app/Http/Requests/Admin/Nodes/TestNodeConnectionRequest.php b/app/Http/Requests/Admin/Nodes/TestNodeConnectionRequest.php new file mode 100644 index 00000000000..b4519de1712 --- /dev/null +++ b/app/Http/Requests/Admin/Nodes/TestNodeConnectionRequest.php @@ -0,0 +1,25 @@ +route('node') instanceof Node + ? 'sometimes|nullable|string|max:191' + : Node::$validationRules['token_id']; + + return [ + 'name' => Node::$validationRules['name'], + 'verify_tls' => 'required|boolean', + 'fqdn' => 'required|string', + 'token_id' => $credentialRules, + 'token_secret' => $credentialRules, + 'port' => Node::$validationRules['port'], + ]; + } +} diff --git a/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php b/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php index 5132f9e6e3c..3f1de7ab747 100644 --- a/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php +++ b/app/Http/Requests/Admin/Nodes/UpdateNodeRequest.php @@ -1,9 +1,9 @@ parameter('node', Node::class)); return [ - ...Arr::except($rules, ['token_id', 'secret']), + ...Arr::except($rules, ['token_id', 'token_secret']), 'token_id' => 'sometimes|string|max:191', - 'secret' => 'sometimes|string|max:191', + 'token_secret' => 'sometimes|string|max:191', ]; } - public function withValidator(Validator $validator): void + public function after(): array { - $validator->after(function (Validator $validator) { - $node = $this->parameter('node', Node::class); - // multiply memory by memory_overallocate (which indicates how much you can go over) percentage - $memory = intval($this->input('memory')) * ((intval( - $this->input('memory_overallocate'), - ) / 100) + 1); - $disk = intval($this->input('disk')) * ((intval( - $this->input('disk_overallocate'), - ) / 100) + 1); - - if ($memory < $node->memory_allocated) { - $validator->errors()->add( - 'memory', 'The memory value is lower than what\'s allocated.', - ); - } + return [ + function (Validator $validator) { + $node = $this->parameter('node', Node::class); + // multiply memory by memory_overallocate (which indicates how much you can go over) percentage + $memory = intval($this->input('memory')) * ((intval( + $this->input('memory_overallocate'), + ) / 100) + 1); - if ($disk < $node->disk_allocated) { - $validator->errors()->add( - 'disk', 'The disk value is lower than what\'s allocated.', - ); - } - }); + if ($memory < $node->memory_allocated) { + $validator->errors()->add( + 'memory', + 'The memory value is lower than what\'s allocated.', + ); + } + }, + ]; } } diff --git a/app/Http/Requests/Admin/RelayFormRequest.php b/app/Http/Requests/Admin/RelayFormRequest.php new file mode 100644 index 00000000000..71a5d0e7832 --- /dev/null +++ b/app/Http/Requests/Admin/RelayFormRequest.php @@ -0,0 +1,17 @@ + ['required', 'string', 'max:191'], + 'public_url' => ['required', 'url:http,https', 'max:2048'], + 'panel_url_override' => ['nullable', 'url:http,https', 'max:2048'], + ]; + } +} diff --git a/app/Http/Requests/Admin/Servers/Disks/AddServerDiskRequest.php b/app/Http/Requests/Admin/Servers/Disks/AddServerDiskRequest.php new file mode 100644 index 00000000000..c8d0b4b0c05 --- /dev/null +++ b/app/Http/Requests/Admin/Servers/Disks/AddServerDiskRequest.php @@ -0,0 +1,47 @@ +parameter('server', Server::class); + + return [ + 'storage_id' => [ + 'required', + 'integer', + 'exists:storages,id', + new StorageAllows(StorageContentType::KVM), + ], + 'size' => [ + 'required', + 'numeric', + 'min:1', + // Reject a disk that won't fit the target storage's free-for-Convoy + // (live physical free − reserve). Fails open when the node is offline. + function (string $attribute, mixed $value, Closure $fail) use ($server) { + $storage = Storage::find($this->input('storage_id')); + if (! $storage instanceof Storage) { + return; + } + + $free = app(LiveStorageService::class)->freeForConvoy($server->node, $storage); + if ($free !== null && (int) $value > $free) { + $fail("The storage \"{$storage->name}\" does not have enough disk space available."); + } + }, + ], + ]; + } +} diff --git a/app/Http/Requests/Admin/Servers/Disks/ResizeServerDiskRequest.php b/app/Http/Requests/Admin/Servers/Disks/ResizeServerDiskRequest.php new file mode 100644 index 00000000000..50ae8131b1d --- /dev/null +++ b/app/Http/Requests/Admin/Servers/Disks/ResizeServerDiskRequest.php @@ -0,0 +1,42 @@ +parameter('server', Server::class); + /** @var ServerDisk $disk */ + $disk = $this->parameter('disk', ServerDisk::class); + + return [ + 'size' => [ + 'required', + 'numeric', + 'min:1', + // Only the *growth* consumes new space; live free already + // reflects the disk's current allocation. Shrink is handled by + // the service (CannotShrinkDiskException). Fails open offline. + function (string $attribute, mixed $value, Closure $fail) use ($server, $disk) { + $delta = (int) $value - (int) $disk->size; + if ($delta <= 0) { + return; + } + + $free = app(LiveStorageService::class)->freeForConvoy($server->node, $disk->storage); + if ($free !== null && $delta > $free) { + $fail("The storage \"{$disk->storage->name}\" does not have enough disk space available."); + } + }, + ], + ]; + } +} diff --git a/app/Http/Requests/Admin/Servers/Presets/ServerPresetRequest.php b/app/Http/Requests/Admin/Servers/Presets/ServerPresetRequest.php new file mode 100644 index 00000000000..e8b97d0cb30 --- /dev/null +++ b/app/Http/Requests/Admin/Servers/Presets/ServerPresetRequest.php @@ -0,0 +1,136 @@ +method() === 'PUT' + ? ServerPreset::getRulesForUpdate($this->parameter('server_preset', ServerPreset::class)) + : ServerPreset::getRules(); + + return [ + 'name' => $rules['name'], + 'description' => $rules['description'], + 'settings' => $rules['settings'], + + /* + * A preset is partial by design: every setting is `nullable`, and + * one that is absent simply leaves the create form's own default + * alone. What is validated here is that the values which *are* + * saved could actually be submitted — a preset that can only fail + * at create time is worse than no preset. + */ + 'settings.node_id' => [ + 'nullable', + 'integer', + 'exists:nodes,id', + // Storage, bridge and extra disks are all node-scoped ids, so + // saving one without its node would produce a preset that + // points at nothing recognisable once applied. + Rule::requiredIf(fn () => $this->hasNodeScopedSettings()), + ], + 'settings.storage_id' => [ + 'nullable', + 'integer', + 'exists:storages,id', + new StorageAllows(StorageContentType::KVM), + ], + + 'settings.cpu' => 'nullable|integer|min:1|max:100000', + // Mebibytes, as typed into the form. + 'settings.memory' => 'nullable|integer|min:128|max:1048576', + 'settings.disk' => 'nullable|integer|min:1|max:10485760', + // Mebibytes, as typed into the form; -1 is unmetered. + 'settings.bandwidth' => 'nullable|integer|min:-1', + // MB/s, with -1 for uncapped — which is why 0 is not allowed: a + // zero cap is a stopped NIC, not an absent one. + 'settings.speed_limit' => ['nullable', 'numeric', 'min:-1', function (string $attribute, mixed $value, Closure $fail) { + if ($value > -1 && $value < 1) { + $fail('The speed limit must be at least 1 MB/s, or -1 for uncapped.'); + } + }], + 'settings.backup_count' => 'nullable|integer|min:-1', + 'settings.backup_size' => 'nullable|integer|min:-1', + + 'settings.disks' => 'nullable|array', + 'settings.disks.*.storage_id' => [ + 'required', + 'integer', + 'exists:storages,id', + new StorageAllows(StorageContentType::KVM), + ], + // GiB, as typed into the form. + 'settings.disks.*.size' => 'required|numeric|min:1', + + 'settings.network_interface_id' => [ + 'nullable', + 'integer', + 'exists:network_interfaces,id', + new NetworkInterfaceBelongsToNode($this->integerOrNull('settings.node_id')), + ], + 'settings.vlan_tag' => [ + 'nullable', + 'integer', + 'min:1', + 'max:4094', + new VlanIsDeclaredOnInterface($this->integerOrNull('settings.network_interface_id')), + ], + 'settings.addresses_ipv4_count' => 'nullable|integer|min:0|max:100', + 'settings.addresses_ipv6_count' => 'nullable|integer|min:0|max:100', + + 'settings.deferred_os_selection' => 'nullable|boolean', + 'settings.should_create_vm' => 'nullable|boolean', + // No `ImageFitsStorage` / `ImageIsAvailable` here: both judge an + // image against the storage and node a server is being built on, + // and a preset is saved long before that build exists. + 'settings.image_uuid' => 'nullable|string|exists:image_definitions,uuid', + 'settings.image_group_uuid' => 'nullable|string|exists:image_groups,uuid', + 'settings.start_on_completion' => 'nullable|boolean', + ]; + } + + /** + * Whether the payload carries any setting that is only meaningful on one + * particular node. + */ + private function hasNodeScopedSettings(): bool + { + return filled($this->input('settings.storage_id')) + || filled($this->input('settings.network_interface_id')) + || filled($this->input('settings.disks')); + } + + private function integerOrNull(string $key): ?int + { + $value = $this->input($key); + + return filled($value) ? (int) $value : null; + } + + /** + * The validated payload with blank settings dropped rather than stored as a + * wall of nulls: "unset" and "explicitly nothing" mean the same thing to a + * preset, and the shorter row is the one an admin can read in the database. + */ + public function attributesForPreset(): array + { + $validated = $this->validated(); + + $validated['settings'] = collect($validated['settings'] ?? []) + ->reject(fn ($value) => $value === null || $value === []) + ->all(); + + return $validated; + } +} diff --git a/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php b/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php index beb4abd3768..576c70f5040 100644 --- a/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php +++ b/app/Http/Requests/Admin/Servers/Settings/UpdateBuildRequest.php @@ -1,12 +1,14 @@ $rules['cpu'], 'memory' => $rules['memory'], 'disk' => $rules['disk'], - 'address_ids' => 'present|nullable|array', + 'network_interface_id' => [ + 'nullable', + 'integer', + 'exists:network_interfaces,id', + new NetworkInterfaceBelongsToNode($server->node_id), + ], + 'vlan_tag' => $rules['vlan_tag'], + 'address_ids' => 'sometimes|nullable|array', 'address_ids.*' => 'integer|exists:ip_addresses,id', - 'snapshot_limit' => $rules['snapshot_limit'], - 'backup_limit' => $rules['backup_limit'], + // NOTE: a dead 'backup_limit' => $rules['backup_limit'] line was removed + // here — that rule key never existed (the column is backup_count_limit), + // so it emitted an undefined-key warning and mapped to a phantom column. 'bandwidth_limit' => $rules['bandwidth_limit'], 'bandwidth_usage' => $rules['bandwidth_usage'], + 'backup_count_limit' => $rules['backup_count_limit'], + 'backup_size_limit' => $rules['backup_size_limit'], + // Persistent NIC speed cap (bytes/s, null = unlimited) and the + // per-server overage-penalty override (null = inherit node/global). + 'speed_limit' => $rules['speed_limit'], + 'overage_penalty' => $rules['overage_penalty'], + 'overage_penalty.action' => $rules['overage_penalty.action'], + 'overage_penalty.rate' => $rules['overage_penalty.rate'], ]; } - public function withValidator(Validator $validator) + public function after(): array { - $validator->after(function ($validator) { - $addressIds = $this->input('address_ids'); + return [ + function (Validator $validator) { + $server = $this->parameter('server', Server::class); + + if ($this->has('address_ids')) { + $addresses = Address::whereIn('id', $this->input('address_ids') ?? [])->get(); - $addresses = Address::whereIn('id', $addressIds)->get(); + foreach ($addresses as $address) { + if ($address->server_id !== null && $address->server_id !== $server->id) { + $validator->errors()->add( + 'address_ids', + 'One or more of the selected addresses are already in use', + ); + break; + } + } + } - $server = $this->parameter('server', Server::class); + // Checked here rather than as a rule on `vlan_tag`: the tag can + // stay untouched while the interface moves under it, which + // still has to be caught. + $vlanTag = $this->has('vlan_tag') ? $this->input('vlan_tag') : $server->vlan_tag; + if (filled($vlanTag)) { + $rule = new VlanIsDeclaredOnInterface( + $this->input('network_interface_id', $server->network_interface_id), + ); - foreach ($addresses as $address) { - if ($address->server_id !== null && $address->server_id !== $server->id) { - $validator->errors()->add( - 'address_ids', - 'One or more of the selected addresses are already in use', + $rule->validate( + 'vlan_tag', + $vlanTag, + fn (string $message) => $validator->errors()->add('vlan_tag', $message), ); - break; } - } - // check if the memory and disk isn't exceeding the node limits - $node = Node::findOrFail($server->node_id)->load('servers'); + // check if the memory and disk isn't exceeding the node limits + $node = Node::findOrFail($server->node_id)->load('servers'); - $nodeMemoryLimit = ($node->memory * (($node->memory_overallocate / 100) + 1)) - ($node->memory_allocated - $server->memory); - $nodeDiskLimit = ($node->disk * (($node->disk_overallocate / 100) + 1)) - ($node->disk_allocated - $server->disk); + $nodeMemoryLimit = ($node->memory * (($node->memory_overallocate / 100) + 1)) - ($node->memory_allocated - $server->memory); + $nodeDiskLimit = ($node->disk * (($node->disk_overallocate / 100) + 1)) - ($node->disk_allocated - $server->disk); - $memory = intval($this->input('memory')); - $disk = intval($this->input('disk')); - if ($memory > $nodeMemoryLimit || $memory < 0) { - $validator->errors()->add('memory', 'The memory value exceeds the node\'s limit.'); - } + $memory = intval($this->input('memory')); + $disk = intval($this->input('disk')); + if ($memory > $nodeMemoryLimit || $memory < 0) { + $validator->errors()->add('memory', 'The memory value exceeds the node\'s limit.'); + } - if ($disk > $nodeDiskLimit || $disk < 0) { - $validator->errors()->add('disk', 'The disk value exceeds the node\'s limit.'); - } - }); + if ($disk > $nodeDiskLimit || $disk < 0) { + $validator->errors()->add('disk', 'The disk value exceeds the node\'s limit.'); + } + }, + ]; } } diff --git a/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php b/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php index 4f4ef2b860f..b3a06db8ce1 100644 --- a/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php +++ b/app/Http/Requests/Admin/Servers/Settings/UpdateDetailsRequest.php @@ -1,9 +1,9 @@ $rules['cpu'], 'limits.memory' => $rules['memory'], 'limits.disk' => $rules['disk'], - 'limits.snapshot_limit' => $rules['snapshot_limit'], 'limits.backup_limit' => $rules['backup_limit'], 'limits.bandwidth_limit' => $rules['bandwidth_limit'], ]; @@ -42,7 +41,7 @@ public function validated($key = null, $default = null): array $data = parent::validated(); // Adjust the limits field to match what is expected by the model. - if (!empty($data['limits'])) { + if (! empty($data['limits'])) { foreach ($data['limits'] as $key => $value) { $data[$key] = $value; } diff --git a/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php b/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php index 2903496910b..a997be276ea 100644 --- a/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php +++ b/app/Http/Requests/Admin/Servers/Settings/UpdateGeneralInfoRequest.php @@ -1,10 +1,10 @@ [...$rules['hostname'], ...[new Hostname]], 'user_id' => $rules['user_id'], 'vmid' => $rules['vmid'], - 'status' => $rules['status'], + 'lifecycle' => $rules['lifecycle'], ]); } } diff --git a/app/Http/Requests/Admin/Servers/StoreServerRequest.php b/app/Http/Requests/Admin/Servers/StoreServerRequest.php index 487a7421269..a411296944f 100644 --- a/app/Http/Requests/Admin/Servers/StoreServerRequest.php +++ b/app/Http/Requests/Admin/Servers/StoreServerRequest.php @@ -1,87 +1,148 @@ $rules['name'], - 'user_id' => $rules['user_id'], 'node_id' => $rules['node_id'], - // TODO: validation should be added for manually setting the vmid - 'vmid' => 'present|nullable|numeric|min:100|max:999999999', + 'storage_id' => [ + ...$rules['storage_id'], + new StorageAllows(StorageContentType::KVM), + ], + 'user_id' => $rules['user_id'], + 'vmid' => ['nullable', 'numeric', 'min:100', 'max:999999999', new VMIDIsAvailable($this->input('node_id'))], 'hostname' => $rules['hostname'], + + // Resource limits 'limits' => 'required|array', - 'limits.cpu' => $rules['cpu'], - 'limits.memory' => $rules['memory'], - 'limits.disk' => $rules['disk'], - 'limits.snapshots' => $rules['snapshot_limit'], - 'limits.backups' => $rules['backup_limit'], + 'limits.cpu' => [...$rules['cpu'], new HasSufficientCPU], + 'limits.memory' => [...$rules['memory'], new HasSufficientMemory], + 'limits.disk' => [...$rules['disk'], new HasSufficientDiskSpace], 'limits.bandwidth' => $rules['bandwidth_limit'], - 'limits.address_ids' => 'sometimes|nullable|array', - 'limits.address_ids.*' => 'integer|exists:ip_addresses,id', - 'account_password' => ['required_if:should_create_server,1', 'string', 'min:8', 'max:191', new Password( - ), new USKeyboardCharacters()], - 'should_create_server' => 'present|boolean', - 'template_uuid' => 'required_if:create_server,1|string|exists:templates,uuid', - 'start_on_completion' => 'present|boolean', + // Persistent NIC speed cap in bytes/s (null = unlimited). + 'limits.speed_limit' => $rules['speed_limit'], + + // Optional secondary/data disks, each on its own storage. The + // primary/OS disk stays `storage_id` + `limits.disk`; these are + // allocated post-clone (see AllocationService::syncDisks). Capacity + // is checked in aggregate by the HasSufficientDiskSpace rule above. + 'limits.disks' => 'sometimes|array', + 'limits.disks.*.storage_id' => ['required', 'integer', 'exists:storages,id', new StorageAllows(StorageContentType::KVM)], + 'limits.disks.*.size' => ['required', 'numeric', 'min:1'], + + // Backup limits + 'limits.backups' => 'required|array', + 'limits.backups.count' => $rules['backup_count_limit'], + 'limits.backups.size' => $rules['backup_size_limit'], + + // IP addresses + 'limits.network_interface_id' => [ + 'required', + 'integer', + 'exists:network_interfaces,id', + new NetworkInterfaceBelongsToNode($this->input('node_id')), + new HasSufficientAddresses($addressAvailabilityService), + ], + 'limits.vlan_tag' => [ + 'nullable', + 'integer', + 'min:1', + 'max:4094', + new VlanIsDeclaredOnInterface($this->input('limits.network_interface_id')), + ], + 'limits.addresses_ipv4_count' => 'nullable|integer|min:0|max:100', + 'limits.addresses_ipv6_count' => 'nullable|integer|min:0|max:100', + // Explicit address ids are optional. With no ids and both counts + // at zero, ServerCreationService deliberately creates an + // addressless server; positive counts use automatic allocation. + 'limits.addresses' => 'sometimes|array', + 'limits.addresses.*' => [ + 'integer', + function ($attribute, $value, $fail) { + $address = Address::with('addressBlock.addressBlockGroup.networkInterfaces')->find($value); + + if (! $address) { + $fail("The address with ID {$value} could not be found."); + + return; + } + + if ($address->server_id) { + $fail("The address with ID {$value} is already allocated to another server."); + } + + $networkInterfaceId = $this->input('limits.network_interface_id'); + if (! $address->addressBlock->addressBlockGroup->networkInterfaces->contains('id', $networkInterfaceId)) { + $fail("The address with ID {$value} does not belong to the selected network interface."); + } + }, + ], + + // Server creation options + 'deferred_os_selection' => 'required|boolean', + 'account_password' => [ + 'nullable', + Rule::requiredIf(fn () => $this->input('should_create_vm') && ! $this->input('deferred_os_selection')), + 'string', + 'min:8', + 'max:191', + ], + 'should_create_vm' => 'required|boolean', + 'image_uuid' => [ + 'nullable', + Rule::requiredIf(fn () => $this->input('should_create_vm') && ! $this->input('deferred_os_selection')), + 'string', + 'exists:image_definitions,uuid', + new ImageIsAvailable, + new ImageFitsStorage, + ], + 'start_on_completion' => 'required|boolean', ]; } - public function withValidator(Validator $validator): void + protected function prepareForValidation(): void { - $validator->after(function ($validator) { - $addressIds = $this->input('limits.address_ids'); - - if (!is_null($addressIds)) { - $addresses = Address::whereIn('id', $addressIds)->get(); - - foreach ($addresses as $address) { - if ($address->server_id !== null) { - $validator->errors()->add( - 'limits.address_ids', - 'One or more of the selected addresses are already in use', - ); - break; - } - } - } - - // check if the memory and disk isn't exceeding the node limits - $node = Node::findOrFail($this->input('node_id'))->load('servers'); - - $nodeMemoryLimit = ($node->memory * (($node->memory_overallocate / 100) + 1)) - $node->memory_allocated; - $nodeDiskLimit = ($node->disk * (($node->disk_overallocate / 100) + 1)) - $node->disk_allocated; - - $memory = intval($this->input('limits.memory')); - $disk = intval($this->input('limits.disk')); - - if ($memory > $nodeMemoryLimit || $memory < 0) { - $validator->errors()->add( - 'limits.memory', 'The memory value exceeds the node\'s limit.', - ); - } - - if ($disk > $nodeDiskLimit || $disk < 0) { - $validator->errors()->add( - 'limits.disk', 'The disk value exceeds the node\'s limit.', - ); - } - }); + $toMerge = []; + + if ($this->input('limits.addresses_ipv4_count', 0) > 0 || $this->input('limits.addresses_ipv6_count', 0) > 0) { + $limits = $this->input('limits', []); + $limits['addresses'] = []; + $toMerge['limits'] = $limits; + } + + if ($this->boolean('deferred_os_selection')) { + $toMerge['should_create_vm'] = false; + $toMerge['start_on_completion'] = false; + $toMerge['account_password'] = null; + $toMerge['image_uuid'] = null; + } + + if (! empty($toMerge)) { + $this->merge($toMerge); + } } } diff --git a/app/Http/Requests/Admin/Settings/TestMailSettingsRequest.php b/app/Http/Requests/Admin/Settings/TestMailSettingsRequest.php new file mode 100644 index 00000000000..7581a63641f --- /dev/null +++ b/app/Http/Requests/Admin/Settings/TestMailSettingsRequest.php @@ -0,0 +1,29 @@ + 'required|string|max:255', + 'port' => 'required|integer|min:1|max:65535', + 'username' => 'nullable|string|max:255', + // Omitted means "use the password already stored", so an admin can test a host or + // port change without retyping a secret the screen never showed them. + 'password' => 'sometimes|nullable|string|max:1024', + 'encryption' => ['required', Rule::enum(MailEncryption::class)], + 'from_address' => 'required|email|max:255', + 'from_name' => 'required|string|max:255', + // Defaults to the acting admin's own address in the controller. + 'recipient' => 'sometimes|nullable|email|max:255', + ]; + } +} diff --git a/app/Http/Requests/Admin/Settings/UpdateAccountSettingsRequest.php b/app/Http/Requests/Admin/Settings/UpdateAccountSettingsRequest.php new file mode 100644 index 00000000000..9194249a573 --- /dev/null +++ b/app/Http/Requests/Admin/Settings/UpdateAccountSettingsRequest.php @@ -0,0 +1,21 @@ + 'required|boolean', + 'allow_email_change' => 'required|boolean', + 'allow_password_change' => 'required|boolean', + 'allow_avatar_change' => 'required|boolean', + ]; + } +} diff --git a/app/Http/Requests/Admin/Settings/UpdateAnchorSettingsRequest.php b/app/Http/Requests/Admin/Settings/UpdateAnchorSettingsRequest.php new file mode 100644 index 00000000000..30317083fd0 --- /dev/null +++ b/app/Http/Requests/Admin/Settings/UpdateAnchorSettingsRequest.php @@ -0,0 +1,17 @@ + 'nullable|url:http,https|max:2048', + ]; + } +} diff --git a/app/Http/Requests/Admin/Settings/UpdateBandwidthSettingsRequest.php b/app/Http/Requests/Admin/Settings/UpdateBandwidthSettingsRequest.php new file mode 100644 index 00000000000..c8cffdb0f67 --- /dev/null +++ b/app/Http/Requests/Admin/Settings/UpdateBandwidthSettingsRequest.php @@ -0,0 +1,21 @@ + 'required|array', + 'overage_penalty.action' => 'required|string|in:throttle,disconnect', + // A rate is only meaningful for a throttle; `disconnect` keeps the + // stored rate untouched so toggling back doesn't lose it. + 'overage_penalty.rate' => 'required_if:overage_penalty.action,throttle|integer|min:1', + ]; + } +} diff --git a/app/Http/Requests/Admin/Settings/UpdateMailSettingsRequest.php b/app/Http/Requests/Admin/Settings/UpdateMailSettingsRequest.php new file mode 100644 index 00000000000..dfedf6852a8 --- /dev/null +++ b/app/Http/Requests/Admin/Settings/UpdateMailSettingsRequest.php @@ -0,0 +1,28 @@ + 'present|nullable|string|max:255', + 'port' => 'required_with:host|nullable|integer|min:1|max:65535', + 'username' => 'nullable|string|max:255', + // Absent means "keep the stored one" — the screen never receives the password, so it + // cannot echo it back. Sending an empty string is the explicit way to clear it. + 'password' => 'sometimes|nullable|string|max:1024', + 'encryption' => ['required_with:host', 'nullable', Rule::enum(MailEncryption::class)], + 'from_address' => 'required_with:host|nullable|email|max:255', + 'from_name' => 'required_with:host|nullable|string|max:255', + ]; + } +} diff --git a/app/Http/Requests/Admin/StoreAnchorEnrollmentKeyRequest.php b/app/Http/Requests/Admin/StoreAnchorEnrollmentKeyRequest.php new file mode 100644 index 00000000000..c9a163c5c4c --- /dev/null +++ b/app/Http/Requests/Admin/StoreAnchorEnrollmentKeyRequest.php @@ -0,0 +1,60 @@ + ['required', 'string', 'max:191'], + // Absent or null admits either mode. + 'mode' => ['sometimes', 'nullable', new Enum(AnchorMode::class)], + // Explicit null means unlimited. See maxUses(). + 'max_uses' => ['sometimes', 'nullable', 'integer', 'min:1'], + // Explicit null means it never expires. See expiresInMinutes(). + 'expires_in_minutes' => ['sometimes', 'nullable', 'integer', 'min:1', 'max:'.self::MAX_TTL_MINUTES], + ]; + } + + public function mode(): ?AnchorMode + { + return $this->enum('mode', AnchorMode::class); + } + + /** + * Null is "unlimited" and has to be asked for by name. + * + * Omitting the field gives a single-use key, so the dangerous shape is the + * one you cannot reach by forgetting a parameter -- which is the only + * reason `sometimes|nullable` is worth the subtlety here. + */ + public function maxUses(): ?int + { + if (! $this->has('max_uses')) { + return 1; + } + + return $this->input('max_uses') === null ? null : $this->integer('max_uses'); + } + + /** Same contract as {@see maxUses()}: absent is the safe default, null is "never". */ + public function expiresInMinutes(): ?int + { + if (! $this->has('expires_in_minutes')) { + return AnchorEnrollmentKeyService::DEFAULT_TTL_MINUTES; + } + + return $this->input('expires_in_minutes') === null + ? null + : $this->integer('expires_in_minutes'); + } +} diff --git a/app/Http/Requests/Admin/Tokens/StoreTokenRequest.php b/app/Http/Requests/Admin/Tokens/StoreTokenRequest.php index cefb0cbd38c..c036218a500 100644 --- a/app/Http/Requests/Admin/Tokens/StoreTokenRequest.php +++ b/app/Http/Requests/Admin/Tokens/StoreTokenRequest.php @@ -1,8 +1,11 @@ 'required|string|between:1,191', + // Omit for a full-access token; otherwise scope it to specific resource abilities. + 'abilities' => 'sometimes|array', + 'abilities.*' => ['string', Rule::in(TokenAbilities::all())], + 'allowed_networks' => ['sometimes', 'array', 'max:100'], + 'allowed_networks.*' => ['required', 'string', 'max:191', new IpAddressOrCidr], ]; } + + /** + * @return list + */ + public function abilities(): array + { + /** @var list $abilities */ + $abilities = $this->input('abilities', ['*']); + + return empty($abilities) ? ['*'] : $abilities; + } + + /** @return list */ + public function allowedNetworks(): array + { + /** @var array $networks */ + $networks = $this->validated('allowed_networks', []); + + return array_values(array_unique(array_map(trim(...), $networks))); + } } diff --git a/app/Http/Requests/Admin/Tokens/UpdateTokenRequest.php b/app/Http/Requests/Admin/Tokens/UpdateTokenRequest.php new file mode 100644 index 00000000000..f2788d3db2e --- /dev/null +++ b/app/Http/Requests/Admin/Tokens/UpdateTokenRequest.php @@ -0,0 +1,32 @@ + ['present', 'array', 'max:100'], + 'allowed_networks.*' => ['required', 'string', 'max:191', new IpAddressOrCidr], + ]; + } + + /** @return list */ + public function allowedNetworks(): array + { + return $this->normalizeNetworks($this->validated('allowed_networks')); + } + + /** @param array $networks + * @return list + */ + private function normalizeNetworks(array $networks): array + { + return array_values(array_unique(array_map(trim(...), $networks))); + } +} diff --git a/app/Http/Requests/Admin/Users/StoreUserRequest.php b/app/Http/Requests/Admin/Users/StoreUserRequest.php index 204131844bf..df977afe2a1 100644 --- a/app/Http/Requests/Admin/Users/StoreUserRequest.php +++ b/app/Http/Requests/Admin/Users/StoreUserRequest.php @@ -1,9 +1,9 @@ $rules['name'], 'email' => $rules['email'], - 'password' => ['required', Password::defaults()], + // Optional now: omitting it invites the account instead, which is the flow that + // exists so nobody has to pick — or email — a password on someone else's behalf. + 'password' => ['nullable', ...PasswordPolicy::rules()], 'root_admin' => $rules['root_admin'], ]; } diff --git a/app/Http/Requests/Admin/Users/UpdateUserRequest.php b/app/Http/Requests/Admin/Users/UpdateUserRequest.php index e7ccc90c9fa..9ad6718f4c1 100644 --- a/app/Http/Requests/Admin/Users/UpdateUserRequest.php +++ b/app/Http/Requests/Admin/Users/UpdateUserRequest.php @@ -1,10 +1,10 @@ input('password') === '') { + $this->merge(['password' => null]); + } + } + /** * Get the validation rules that apply to the request. * @@ -30,7 +42,7 @@ public function rules(): array return [ 'name' => $rules['name'], 'email' => $rules['email'], - 'password' => [Password::defaults(), 'nullable'], + 'password' => ['nullable', ...PasswordPolicy::rules()], 'root_admin' => $rules['root_admin'], ]; } diff --git a/app/Http/Requests/Anchor/ConsumeEnrollmentRequest.php b/app/Http/Requests/Anchor/ConsumeEnrollmentRequest.php new file mode 100644 index 00000000000..b758dfc046c --- /dev/null +++ b/app/Http/Requests/Anchor/ConsumeEnrollmentRequest.php @@ -0,0 +1,87 @@ + ['required', 'string', 'max:255'], + + /* + * Absent on the targeted path, where the mode is already recorded + * against the Anchor and the agent is told what it is. Required to + * self-register, because there is nothing yet to disagree with. + */ + 'mode' => ['sometimes', new Enum(AnchorMode::class)], + + /* + * The machine's self-description. Every field is optional: an older + * agent gathers less, and refusing enrollment over a fact nobody + * schedules against would be a poor trade. What is *validated* is + * the shape, so that a garbage report cannot be stored as though it + * were evidence. + * + * Nothing here may grant privilege -- no location, no relay, no + * approval. Those are decisions, and a decision cannot arrive in + * the same envelope as the request for it. + */ + 'report' => ['sometimes', 'array'], + 'report.hostname' => ['sometimes', 'nullable', 'string', 'max:255'], + 'report.pve_node_name' => ['sometimes', 'nullable', 'string', 'max:191'], + 'report.pve_version' => ['sometimes', 'nullable', 'string', 'max:64'], + 'report.cluster_name' => ['sometimes', 'nullable', 'string', 'max:191'], + 'report.cluster_ca_fingerprint' => ['sometimes', 'nullable', 'string', 'max:191'], + 'report.cpu' => ['sometimes', 'nullable', 'array'], + 'report.cpu.sockets' => ['sometimes', 'nullable', 'integer', 'min:1', 'max:1024'], + 'report.cpu.cores' => ['sometimes', 'nullable', 'integer', 'min:1', 'max:8192'], + 'report.cpu.threads' => ['sometimes', 'nullable', 'integer', 'min:1', 'max:16384'], + 'report.memory_bytes' => ['sometimes', 'nullable', 'integer', 'min:1'], + 'report.addresses' => ['sometimes', 'nullable', 'array', 'max:32'], + 'report.addresses.*' => ['string', 'ip'], + 'report.version' => ['sometimes', 'nullable', 'string', 'max:64'], + 'report.protocol' => ['sometimes', 'nullable', 'array'], + 'report.protocol.min' => ['sometimes', 'nullable', 'integer', 'min:1'], + 'report.protocol.max' => ['sometimes', 'nullable', 'integer', 'min:1'], + 'report.capabilities' => ['sometimes', 'nullable', 'array', 'max:32'], + 'report.capabilities.*' => ['string', 'max:191'], + ]; + } + + /** Defaults to an agent: the mode that has to be installed on a host to be useful. */ + public function mode(): AnchorMode + { + return $this->enum('mode', AnchorMode::class) ?? AnchorMode::AGENT; + } + + /** + * The validated report, plus what only the panel can observe. + * + * The source address is recorded because it is the one reachability claim + * the machine cannot overstate -- it is where the request actually came + * from. Approval uses it as a candidate; nothing dials it unverified. + * + * @return array + */ + public function report(): array + { + /** @var array $report */ + $report = $this->validated()['report'] ?? []; + + return [ + ...$report, + 'observed_source_ip' => $this->ip(), + 'observed_at' => now()->toIso8601String(), + ]; + } +} diff --git a/app/Http/Requests/Anchor/HeartbeatRequest.php b/app/Http/Requests/Anchor/HeartbeatRequest.php new file mode 100644 index 00000000000..ed4b4958182 --- /dev/null +++ b/app/Http/Requests/Anchor/HeartbeatRequest.php @@ -0,0 +1,25 @@ + ['required', 'string', 'max:191'], + 'mode' => ['required', 'string', 'in:agent,relay'], + 'protocol.min' => ['required', 'integer', 'min:1'], + 'protocol.max' => ['required', 'integer', 'gte:protocol.min'], + 'capabilities' => ['required', 'array'], + 'capabilities.*' => ['string', 'max:191'], + ]; + } +} diff --git a/app/Http/Requests/Auth/AcceptInviteRequest.php b/app/Http/Requests/Auth/AcceptInviteRequest.php new file mode 100644 index 00000000000..807d204ed13 --- /dev/null +++ b/app/Http/Requests/Auth/AcceptInviteRequest.php @@ -0,0 +1,27 @@ + ['required', 'confirmed', ...PasswordPolicy::rules()], + ]; + } +} diff --git a/app/Http/Requests/Auth/ConfirmIdentityRequest.php b/app/Http/Requests/Auth/ConfirmIdentityRequest.php new file mode 100644 index 00000000000..604270fd26d --- /dev/null +++ b/app/Http/Requests/Auth/ConfirmIdentityRequest.php @@ -0,0 +1,24 @@ + ['nullable', 'json', 'bail', function ($attribute, $value, $fail) { + if ($this->has('password')) { + $fail('Only one of passkey or password can be provided.'); + } + }], + 'password' => ['nullable', 'string', 'bail', function ($attribute, $value, $fail) { + if ($this->has('passkey')) { + $fail('Only one of passkey or password can be provided.'); + } + }], + ]; + } +} diff --git a/app/Http/Requests/Auth/LoginRequest.php b/app/Http/Requests/Auth/LoginRequest.php index 360e6b472c0..1196f7108f6 100644 --- a/app/Http/Requests/Auth/LoginRequest.php +++ b/app/Http/Requests/Auth/LoginRequest.php @@ -1,12 +1,12 @@ ensureIsNotRateLimited(); - if (!Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) { + if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) { RateLimiter::hit($this->throttleKey()); throw ValidationException::withMessages([ @@ -59,7 +59,7 @@ public function authenticate(): void */ public function ensureIsNotRateLimited(): void { - if (!RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { + if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) { return; } @@ -80,6 +80,6 @@ public function ensureIsNotRateLimited(): void */ public function throttleKey(): string { - return Str::lower($this->input('email')) . '|' . $this->ip(); + return Str::lower($this->input('email')).'|'.$this->ip(); } } diff --git a/app/Http/Requests/Auth/Passkeys/RenamePasskeyRequest.php b/app/Http/Requests/Auth/Passkeys/RenamePasskeyRequest.php new file mode 100644 index 00000000000..fc5c251c257 --- /dev/null +++ b/app/Http/Requests/Auth/Passkeys/RenamePasskeyRequest.php @@ -0,0 +1,15 @@ +code &&` — so + * posting any code as such a user threw a DecryptException out of the request + * and answered 500 instead of rejecting the attempt. The challenge screen hides + * the field for them (`authenticator: false`), but the endpoint is reachable + * regardless of what the UI offers. + * + * The recovery-code path is unaffected: it reads recoveryCodes(), which every + * second factor populates. + */ +class SecondFactorLoginRequest extends TwoFactorLoginRequest +{ + public function hasValidCode() + { + if (blank($this->challengedUser()->two_factor_secret)) { + return false; + } + + return parent::hasValidCode(); + } +} diff --git a/app/Http/Requests/Base/LocaleRequest.php b/app/Http/Requests/Base/LocaleRequest.php deleted file mode 100644 index 185aaf9c486..00000000000 --- a/app/Http/Requests/Base/LocaleRequest.php +++ /dev/null @@ -1,16 +0,0 @@ - ['required', 'string', 'in:en_US en'], - 'namespace' => ['required', 'string', 'regex:/^(?!.*\.\.)[A-Za-z_. ]{1,191}$/'], - ]; - } -} \ No newline at end of file diff --git a/app/Http/Requests/BaseApiRequest.php b/app/Http/Requests/BaseApiRequest.php index e775ca335d3..16bcdb96f2a 100644 --- a/app/Http/Requests/BaseApiRequest.php +++ b/app/Http/Requests/BaseApiRequest.php @@ -1,12 +1,12 @@ passesAuthorization()) { + if (! $this->passesAuthorization()) { $this->failedAuthorization(); } @@ -54,7 +54,7 @@ protected function passesAuthorization(): bool return true; } - if (!parent::passesAuthorization()) { + if (! parent::passesAuthorization()) { return false; } @@ -90,20 +90,18 @@ public function requiredToOptional(array $rules): array * * @template T of Model * - * @param class-string $expect + * @param class-string $expect * @return T * * @noinspection PhpDocSignatureInspection */ - public function parameter(string $key, string $expect) + public function parameter(string $key, string $expect): Model { $value = $this->route()->parameter($key); Assert::isInstanceOf($value, $expect); - Assert::isInstanceOf($value, Model::class); Assert::true($value->exists); - /* @var T $value */ return $value; } } diff --git a/app/Http/Requests/Client/Account/StoreApiKeyRequest.php b/app/Http/Requests/Client/Account/StoreApiKeyRequest.php new file mode 100644 index 00000000000..ee9012e3db6 --- /dev/null +++ b/app/Http/Requests/Client/Account/StoreApiKeyRequest.php @@ -0,0 +1,31 @@ + 'required|string|between:1,191', + // Omit for a full-access token; otherwise scope it to specific resource abilities. + 'abilities' => 'sometimes|array', + 'abilities.*' => ['string', Rule::in(AccountTokenAbilities::all())], + ]; + } + + /** + * @return list + */ + public function abilities(): array + { + /** @var list $abilities */ + $abilities = $this->input('abilities', ['*']); + + return empty($abilities) ? ['*'] : $abilities; + } +} diff --git a/app/Http/Requests/Client/Account/StoreSSHKeyRequest.php b/app/Http/Requests/Client/Account/StoreSSHKeyRequest.php new file mode 100644 index 00000000000..8d4c55f17d9 --- /dev/null +++ b/app/Http/Requests/Client/Account/StoreSSHKeyRequest.php @@ -0,0 +1,17 @@ + 'required|string|max:40', + 'public_key' => ['required', 'string', 'max:500', new SshPublicKey], + ]; + } +} diff --git a/app/Http/Requests/Client/DeleteAvatarRequest.php b/app/Http/Requests/Client/DeleteAvatarRequest.php new file mode 100644 index 00000000000..b4ee81f15dc --- /dev/null +++ b/app/Http/Requests/Client/DeleteAvatarRequest.php @@ -0,0 +1,28 @@ +for($this->user())->canChangeAvatar; + } + + public function rules(): array + { + return []; + } +} diff --git a/app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php b/app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php index a5fcf58a827..e85583f10ae 100644 --- a/app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php +++ b/app/Http/Requests/Client/Servers/Backups/DeleteBackupRequest.php @@ -1,9 +1,9 @@ user()->can('createConsoleSession', $this->parameter('server', Server::class)); + return $this->user()->can( + 'createConsoleSession', + $this->parameter('server', Server::class), + ); } public function rules(): array { - $server = $this->parameter('server', Server::class); - return [ - 'type' => [$server->node->coterm_enabled ? 'required' : 'exclude', new Enum(ConsoleType::class)], + 'type' => ['required', new Enum(ConsoleType::class)], ]; } } diff --git a/app/Http/Requests/Client/Servers/Firewall/DeleteFirewallRuleRequest.php b/app/Http/Requests/Client/Servers/Firewall/DeleteFirewallRuleRequest.php new file mode 100644 index 00000000000..275f853c3be --- /dev/null +++ b/app/Http/Requests/Client/Servers/Firewall/DeleteFirewallRuleRequest.php @@ -0,0 +1,23 @@ +user()->can('manageFirewall', $this->route('server')); + } + + public function rules(): array + { + return [ + // Optional, but the UI always sends it: positions renumber on + // every write, so a stale index would otherwise delete whichever + // rule has since taken that slot. + 'digest' => ['nullable', 'string', 'max:64'], + ]; + } +} diff --git a/app/Http/Requests/Client/Servers/Firewall/FirewallRuleRequest.php b/app/Http/Requests/Client/Servers/Firewall/FirewallRuleRequest.php new file mode 100644 index 00000000000..a9c215926b2 --- /dev/null +++ b/app/Http/Requests/Client/Servers/Firewall/FirewallRuleRequest.php @@ -0,0 +1,97 @@ +user()->can('manageFirewall', $this->route('server')); + } + + public function rules(): array + { + return [ + 'direction' => ['required', new Enum(RuleDirection::class)], + 'action' => ['required', new Enum(RuleAction::class)], + 'enabled' => ['required', 'boolean'], + + // A macro already carries a protocol and port, so accepting both + // would let the UI submit a rule Proxmox then rejects for reasons + // the user cannot see from the form. + 'macro' => ['nullable', 'string', 'max:128', 'prohibits:protocol,destination_port'], + + 'protocol' => ['nullable', 'string', 'max:32'], + 'source_address' => ['nullable', 'string', 'max:512'], + 'destination_address' => ['nullable', 'string', 'max:512'], + 'source_port' => ['nullable', 'string', 'max:512'], + 'destination_port' => ['nullable', 'string', 'max:512'], + + // Proxmox only accepts this alongside an ICMP protocol, and + // rejects the whole rule otherwise. + 'icmp_type' => [ + 'nullable', + 'string', + 'max:64', + Rule::prohibitedIf(fn () => ! in_array( + strtolower((string) $this->input('protocol')), + self::ICMP_PROTOCOLS, + true, + )), + ], + + // For a guest, `iface` must name one of its own network devices. + 'interface' => ['nullable', 'string', 'regex:/^net\d+$/'], + + 'log_level' => ['nullable', new Enum(FirewallLogLevel::class)], + 'comment' => ['nullable', 'string', 'max:255'], + + // The digest the client last read the ruleset at. Positions + // renumber on every write, so without this a delete or edit aimed + // at "rule 2" can land on a rule the user never saw. + 'digest' => ['nullable', 'string', 'max:64'], + ]; + } + + /** + * The validated rule, in domain terms. + */ + public function toRuleData(): FirewallRuleData + { + return new FirewallRuleData( + position: null, + direction: RuleDirection::from($this->validated('direction')), + action: RuleAction::from($this->validated('action')), + isEnabled: $this->boolean('enabled'), + macro: $this->validated('macro'), + protocol: $this->validated('protocol'), + sourceAddress: $this->validated('source_address'), + destinationAddress: $this->validated('destination_address'), + sourcePort: $this->validated('source_port'), + destinationPort: $this->validated('destination_port'), + icmpType: $this->validated('icmp_type'), + interface: $this->validated('interface'), + logLevel: ($level = $this->validated('log_level')) ? FirewallLogLevel::from($level) : null, + comment: $this->validated('comment'), + digest: $this->validated('digest'), + ); + } +} diff --git a/app/Http/Requests/Client/Servers/Firewall/MoveFirewallRuleRequest.php b/app/Http/Requests/Client/Servers/Firewall/MoveFirewallRuleRequest.php new file mode 100644 index 00000000000..aa0e5c56a23 --- /dev/null +++ b/app/Http/Requests/Client/Servers/Firewall/MoveFirewallRuleRequest.php @@ -0,0 +1,21 @@ +user()->can('manageFirewall', $this->route('server')); + } + + public function rules(): array + { + return [ + 'position' => ['required', 'integer', 'min:0'], + 'digest' => ['nullable', 'string', 'max:64'], + ]; + } +} diff --git a/app/Http/Requests/Client/Servers/Firewall/StoreFirewallRuleRequest.php b/app/Http/Requests/Client/Servers/Firewall/StoreFirewallRuleRequest.php new file mode 100644 index 00000000000..b46c862b91e --- /dev/null +++ b/app/Http/Requests/Client/Servers/Firewall/StoreFirewallRuleRequest.php @@ -0,0 +1,15 @@ + ['nullable', 'integer', 'min:0'], + ]); + } +} diff --git a/app/Http/Requests/Client/Servers/Firewall/UpdateFirewallOptionsRequest.php b/app/Http/Requests/Client/Servers/Firewall/UpdateFirewallOptionsRequest.php new file mode 100644 index 00000000000..c95ccf2edb2 --- /dev/null +++ b/app/Http/Requests/Client/Servers/Firewall/UpdateFirewallOptionsRequest.php @@ -0,0 +1,37 @@ +user()->can('manageFirewall', $this->route('server')); + } + + public function rules(): array + { + return [ + 'inbound_policy' => ['required', new Enum(FirewallPolicy::class)], + 'outbound_policy' => ['required', new Enum(FirewallPolicy::class)], + 'inbound_log_level' => ['required', new Enum(FirewallLogLevel::class)], + 'outbound_log_level' => ['required', new Enum(FirewallLogLevel::class)], + + // The digest the client last read. Optional so an API consumer can + // opt out of the check, but the UI always sends it. + 'digest' => ['nullable', 'string', 'max:64'], + ]; + } +} diff --git a/app/Http/Requests/Client/Servers/Firewall/UpdateFirewallRuleRequest.php b/app/Http/Requests/Client/Servers/Firewall/UpdateFirewallRuleRequest.php new file mode 100644 index 00000000000..625bd8c4aaf --- /dev/null +++ b/app/Http/Requests/Client/Servers/Firewall/UpdateFirewallRuleRequest.php @@ -0,0 +1,10 @@ + ['required', Rule::enum(StatisticTimeRange::class)], + 'consolidator' => ['nullable', Rule::enum(StatisticConsolidatorFunction::class)], + ]; + } + + public function authorize(): bool + { + return true; + } +} diff --git a/app/Http/Requests/Client/Servers/RetryInstallationRequest.php b/app/Http/Requests/Client/Servers/RetryInstallationRequest.php new file mode 100644 index 00000000000..83162b64b7e --- /dev/null +++ b/app/Http/Requests/Client/Servers/RetryInstallationRequest.php @@ -0,0 +1,30 @@ +parameter('server', Server::class); + + // Exempt from AuthenticateServerAccess (a failed install is by definition not ready), + // so suspension is only enforced here. + return ! $server->isSuspended() && $server->lifecycle === ServerLifecycle::INSTALL_FAILED; + } + + /** + * Get the validation rules that apply to the request. + */ + public function rules(): array + { + return []; + } +} diff --git a/app/Http/Requests/Client/Servers/SendPowerCommandRequest.php b/app/Http/Requests/Client/Servers/SendPowerCommandRequest.php deleted file mode 100644 index 6c35636cb5a..00000000000 --- a/app/Http/Requests/Client/Servers/SendPowerCommandRequest.php +++ /dev/null @@ -1,24 +0,0 @@ -user()->can('sendPowerCommand', $this->parameter('server', Server::class)); - } - - public function rules(): array - { - return [ - 'state' => ['required', new Enum(PowerAction::class)], - ]; - } -} diff --git a/app/Http/Requests/Client/Servers/Settings/MediaRequest.php b/app/Http/Requests/Client/Servers/Settings/MediaRequest.php new file mode 100644 index 00000000000..5458f1c5d9c --- /dev/null +++ b/app/Http/Requests/Client/Servers/Settings/MediaRequest.php @@ -0,0 +1,30 @@ +parameter('iso', ISO::class); + + return ! $iso->hidden || $this->user()->root_admin; + } + + public function rules(): array + { + return []; + } +} diff --git a/app/Http/Requests/Client/Servers/Settings/MountMediaRequest.php b/app/Http/Requests/Client/Servers/Settings/MountMediaRequest.php deleted file mode 100644 index c71ae9d1e4e..00000000000 --- a/app/Http/Requests/Client/Servers/Settings/MountMediaRequest.php +++ /dev/null @@ -1,28 +0,0 @@ -parameter('iso', ISO::class); - - // Only the hidden flag is checked here. That the ISO belongs to the - // server's node is settled before this runs, by the scoped route-model - // binding resolving {iso} through Server::isos() — see RouteScopingTest. - if ($iso->hidden && !$this->user()->root_admin) { - return false; - } - - return true; - } - - public function rules(): array - { - return []; - } -} diff --git a/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php b/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php index cc34aaabb02..b5b88263714 100644 --- a/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/ReinstallServerRequest.php @@ -1,12 +1,16 @@ parameter('server', Server::class); + + // This route is exempt from AuthenticateServerAccess (a server awaiting OS selection + // has to reach it), so the suspension check has to happen here or not at all. + if ($server->isSuspended()) { + return false; + } + + // Rebuilding a live server destroys its disk, so it gets the same identity gate as + // the other irreversible acts (setting a root password, minting a token) rather than + // trusting a live cookie alone. The gate is on the rebuild branch only: a server in + // DEFERRED_OS_SELECTION has nothing to erase, and gating its first install would + // stop a brand-new account from reaching a usable server at all. + if ($server->isReady() && ! IdentityConfirmation::isConfirmed($this->session())) { + throw new AccessDeniedHttpException('Your identity must be confirmed to rebuild a server.'); + } + + return $server->isReady() || $server->lifecycle === ServerLifecycle::DEFERRED_OS_SELECTION; } /** @@ -26,23 +47,51 @@ public function authorize(): bool public function rules(): array { return [ - 'template_uuid' => 'required|string|exists:templates,uuid', - 'account_password' => ['required', 'string', 'min:8', 'max:191', new Password( - ), new USKeyboardCharacters()], + 'image_uuid' => [ + 'required', + 'string', + 'exists:image_definitions,uuid', + new ImageIsAvailable, + new ImageFitsStorage, + ], + 'account_password' => ['required', 'string', 'min:8', 'max:191'], 'start_on_completion' => 'present|boolean', ]; } - // check if the template belongs to the same node as the server - public function withValidator($validator) + /** + * Prepare the data for validation. + */ + protected function prepareForValidation(): void { - $validator->after(function ($validator) { - $template = Template::where('uuid', '=', $this->template_uuid)->firstOrFail(); - $server = $this->parameter('server', Server::class); - - if ($server->node_id !== $template->group->node_id) { - $validator->errors()->add('template_uuid', 'The selected template is invalid.'); - } - }); + parent::prepareForValidation(); + + $server = $this->parameter('server', Server::class); + + $this->merge([ + 'node_id' => $server->node_id, + 'limits' => [ + 'disk' => $server->disk, + ], + ]); + } + + /** + * Get the validation hooks for the request. + */ + public function after(): array + { + return [ + function (Validator $validator) { + $image = ImageDefinition::where('uuid', '=', $this->image_uuid)->first(); + + // The group carries the same flag, and hiding a group has to + // hide what is inside it -- otherwise an admin-only OS is one + // guessed uuid away from anyone. + if ($image && ($image->is_admin_only || $image->group->is_admin_only) && ! $this->user()->root_admin) { + $validator->errors()->add('image_uuid', 'You are not authorized to use this image.'); + } + }, + ]; } } diff --git a/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php b/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php index 101065e7eda..7267c23ae2b 100644 --- a/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/RenameServerRequest.php @@ -1,11 +1,10 @@ input('type') === AuthenticationType::PASSWORD->value + && ! IdentityConfirmation::isConfirmed($this->session())) { + throw new AccessDeniedHttpException('Your identity must be confirmed to set a root password.'); + } + return $this->user()->can('updateAuthSettings', $this->parameter('server', Server::class)); } @@ -24,28 +37,29 @@ public function rules(): array return [ 'type' => [new Enum(AuthenticationType::class), 'required'], 'ssh_keys' => ['nullable', 'string', 'exclude_unless:type,ssh_keys'], - 'password' => ['string', 'min:8', 'max:191', new Password(), new USKeyboardCharacters( - ), 'exclude_unless:type,password'], + 'password' => ['string', 'min:8', 'max:191', new Password, new USKeyboardCharacters, 'exclude_unless:type,password'], ]; } - public function withValidator(Validator $validator) + public function after(): array { - $validator->after(function ($validator) { - $type = $this->request->get('type'); - $sshKeys = explode(PHP_EOL, $this->request->get('ssh_keys')); + return [ + function (Validator $validator) { + $type = $this->request->get('type'); + $sshKeys = explode(PHP_EOL, $this->request->get('ssh_keys')); - if ($type === AuthenticationType::KEY->value) { - try { - foreach ($sshKeys as $key) { - if (strlen($key) > 0) { - PublicKeyLoader::load($key); + if ($type === AuthenticationType::KEY->value) { + try { + foreach ($sshKeys as $key) { + if (strlen($key) > 0) { + PublicKeyLoader::load($key); + } } + } catch (Exception $e) { + $validator->errors()->add('ssh_keys', 'The SSH key(s) are invalid.'); } - } catch (Exception $e) { - $validator->errors()->add('ssh_keys', 'The SSH key(s) are invalid.'); } - } - }); + }, + ]; } } diff --git a/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php b/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php index 01331e15532..fb08a09a1ed 100644 --- a/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php +++ b/app/Http/Requests/Client/Servers/Settings/UpdateBiosTypeRequest.php @@ -1,12 +1,11 @@ for($this->user())->canChangeAvatar; + } + + public function rules(): array + { + return [ + /* + * A ceiling on what the panel is willing to decode, not on what the + * user may choose: a phone photo is a couple of megabytes and the + * stored result is the same ~30KB either way. `image` reads the + * file's header rather than its name, and the service re-checks the + * format it actually got before handing anything to GD. + */ + 'avatar' => ['required', 'file', 'image', 'mimes:jpeg,jpg,png,webp,gif', 'max:10240'], + + /* + * The square the user framed, in the source picture's own pixels. + * All three or none -- a half-specified crop is a bug on the way + * in, not something to guess the rest of. Bounds are checked + * against the decoded image rather than here, since nothing at + * this point knows how big it is. + */ + 'crop_x' => ['nullable', 'integer', 'min:0', 'required_with:crop_y,crop_size'], + 'crop_y' => ['nullable', 'integer', 'min:0', 'required_with:crop_x,crop_size'], + 'crop_size' => ['nullable', 'integer', 'min:1', 'required_with:crop_x,crop_y'], + ]; + } + + public function messages(): array + { + return [ + 'avatar.max' => 'Pictures must be under 10 MB.', + 'avatar.mimes' => 'Use a JPEG, PNG, WebP or GIF.', + ]; + } +} diff --git a/app/Http/Requests/Client/UpdateEmailRequest.php b/app/Http/Requests/Client/UpdateEmailRequest.php new file mode 100644 index 00000000000..4e77e3a6b08 --- /dev/null +++ b/app/Http/Requests/Client/UpdateEmailRequest.php @@ -0,0 +1,32 @@ +for($this->user())->canChangeEmail; + } + + public function rules(): array + { + return [ + 'email' => [ + 'required', + 'email', + 'between:1,191', + Rule::unique('users', 'email')->ignore($this->user()->id), + ], + ]; + } +} diff --git a/app/Http/Requests/Client/UpdatePasswordRequest.php b/app/Http/Requests/Client/UpdatePasswordRequest.php new file mode 100644 index 00000000000..6c3901b8e57 --- /dev/null +++ b/app/Http/Requests/Client/UpdatePasswordRequest.php @@ -0,0 +1,43 @@ + ['required', 'string', 'current_password:web'], + // The policy itself — length, breach check, bcrypt's byte ceiling, and deliberately + // no character-composition rules — lives in PasswordPolicy so the admin endpoints + // that set somebody else's password hold to the same bar. + 'password' => ['required', 'confirmed', ...PasswordPolicy::rules()], + ]; + } + + public function messages(): array + { + return [ + 'current_password.current_password' => __('The provided password does not match your current password.'), + ]; + } + + /** + * Overridden away from the base class's admin check — this is the account acting on itself — + * and then narrowed by the panel-wide policy, which an operator turns off when sign-in + * credentials are owned elsewhere (an OIDC directory, say) and a local password change would + * change nothing that actually logs the person in. + * + * There is no password-reset flow to gate alongside it: Fortify's `resetPasswords` feature is + * not enabled, so this endpoint is the only way an account changes its own password. + */ + public function authorize(): bool + { + // Resolved rather than injected: the base class fixes this signature. + return app(AccountPolicyResolver::class)->for($this->user())->canChangePassword; + } +} diff --git a/app/Http/Requests/Client/UpdateProfileRequest.php b/app/Http/Requests/Client/UpdateProfileRequest.php new file mode 100644 index 00000000000..3ba0d926200 --- /dev/null +++ b/app/Http/Requests/Client/UpdateProfileRequest.php @@ -0,0 +1,29 @@ +for($this->user())->canChangeName; + } + + public function rules(): array + { + return [ + 'name' => ['required', 'string', 'between:1,191'], + ]; + } +} diff --git a/app/Http/Requests/Coterm/StoreSessionRequest.php b/app/Http/Requests/Coterm/StoreSessionRequest.php deleted file mode 100644 index b6735465423..00000000000 --- a/app/Http/Requests/Coterm/StoreSessionRequest.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ - public function rules(): array - { - return [ - 'type' => ['required', new Enum(ConsoleType::class)], - ]; - } -} diff --git a/app/Http/Requests/Servers/SendPowerCommandRequest.php b/app/Http/Requests/Servers/SendPowerCommandRequest.php new file mode 100644 index 00000000000..a482a04842e --- /dev/null +++ b/app/Http/Requests/Servers/SendPowerCommandRequest.php @@ -0,0 +1,30 @@ +user()->can('sendPowerCommand', $this->parameter('server', Server::class)); + } + + public function rules(): array + { + return [ + // A command, not a state: `start` is an instruction to the hypervisor, and the + // state it produces (`running`) has a different name. See PowerCommand. + 'command' => ['required', new Enum(PowerCommand::class)], + ]; + } +} diff --git a/app/Jobs/Backup/BatchPurgeServerBackupsJob.php b/app/Jobs/Backup/BatchPurgeServerBackupsJob.php new file mode 100644 index 00000000000..94e7ba4a30f --- /dev/null +++ b/app/Jobs/Backup/BatchPurgeServerBackupsJob.php @@ -0,0 +1,42 @@ +server->backups() + ->whereNull('error_code') + ->whereNotNull('completed_at') + ->chunkById(100, function (Collection $backups) { + $this->batch()->add($backups->map(fn (Backup $backup) => new DeleteBackupJob($backup))); + }, column: 'id'); + } +} diff --git a/app/Jobs/Backup/DeleteBackupJob.php b/app/Jobs/Backup/DeleteBackupJob.php new file mode 100644 index 00000000000..d99d2d8f96e --- /dev/null +++ b/app/Jobs/Backup/DeleteBackupJob.php @@ -0,0 +1,46 @@ +setServer($this->backup->server)->delete($this->backup); + + $this->batch()->add(new WaitUntilBackupIsDeletedJob($this->backup)); + } +} diff --git a/app/Jobs/Backup/WaitUntilBackupIsDeletedJob.php b/app/Jobs/Backup/WaitUntilBackupIsDeletedJob.php new file mode 100644 index 00000000000..b08833e742e --- /dev/null +++ b/app/Jobs/Backup/WaitUntilBackupIsDeletedJob.php @@ -0,0 +1,48 @@ +addMinutes(15); + } + + public function __construct( + #[WithoutRelations] + public Backup $backup, + ) {} + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function handle(ProxmoxBackupClient $client): void + { + $backups = $client->setServer($this->backup->server)->getBackups($this->backup->storage); + + if (filled($backups->where('filename', $this->backup->file_name)->first())) { + $this->release(3); + } else { + $this->backup->delete(); + } + } +} diff --git a/app/Jobs/Middleware/ExpiringWithoutOverlapping.php b/app/Jobs/Middleware/ExpiringWithoutOverlapping.php new file mode 100644 index 00000000000..c6a82d05137 --- /dev/null +++ b/app/Jobs/Middleware/ExpiringWithoutOverlapping.php @@ -0,0 +1,44 @@ +addDay(); - } + public int $tries = 1; - public function __construct(protected int $isoId, protected string $upid) - { - } + public function __construct(protected int $isoId, protected string $upid) {} - public function middleware() + public function handle(): void { - return [new WithoutOverlapping("node:iso.download#{$this->isoId}")]; - } - - public function handle(IsoMonitorService $service): void - { - $iso = ISO::findOrFail($this->isoId); - - $service->checkDownloadProgress($iso, $this->upid, fn () => $this->release(3)); + Log::info('Discarding an ISO download monitor queued before the library moved into the panel.', [ + 'iso' => $this->isoId, + 'exists' => ISO::whereKey($this->isoId)->exists(), + ]); } } diff --git a/app/Jobs/Node/PollNodeStatusJob.php b/app/Jobs/Node/PollNodeStatusJob.php new file mode 100644 index 00000000000..7cf7a25f255 --- /dev/null +++ b/app/Jobs/Node/PollNodeStatusJob.php @@ -0,0 +1,41 @@ +nodeId); + + // The node may have been deleted between the poll being queued and run. + if (! $node) { + return; + } + + $service->handle($node); + } +} diff --git a/app/Jobs/Node/PruneUsersJob.php b/app/Jobs/Node/PruneUsersJob.php index 0c1e7183974..020fd043071 100644 --- a/app/Jobs/Node/PruneUsersJob.php +++ b/app/Jobs/Node/PruneUsersJob.php @@ -1,9 +1,9 @@ nodeId); - - $service->handle($node); - } -} diff --git a/app/Jobs/Node/SyncServerUsagesJob.php b/app/Jobs/Node/SyncServerUsagesJob.php index 710ddaa5205..4e513a82757 100644 --- a/app/Jobs/Node/SyncServerUsagesJob.php +++ b/app/Jobs/Node/SyncServerUsagesJob.php @@ -1,9 +1,9 @@ addressBlock->addresses() + ->whereNotNull('server_id') + ->with('server') + ->get() + ->pluck('server') + ->unique('id') + ->filter(fn (Server $server) => $server->exists); + + // If no servers are found, exit early + if ($servers->isEmpty()) { + return; + } + + // Create a batch of SyncNetworkSettingsJob for each server + $jobs = $servers->map(fn (Server $server) => new SyncNetworkSettingsJob($server))->toArray(); + + Bus::batch($jobs) + ->name('Sync network settings for address block #'.$this->addressBlock->id) + ->allowFailures() + ->dispatch(); + } +} diff --git a/app/Jobs/Server/BuildServerJob.php b/app/Jobs/Server/BuildServerJob.php deleted file mode 100644 index 20abf957c83..00000000000 --- a/app/Jobs/Server/BuildServerJob.php +++ /dev/null @@ -1,45 +0,0 @@ -serverId}", - )]; - } - - public function handle(ServerBuildService $service): void - { - $server = Server::findOrFail($this->serverId); - $template = Template::findOrFail($this->templateId); - - $server->update(['status' => Status::INSTALLING->value]); - - $service->build($server, $template); - } -} diff --git a/app/Jobs/Server/CloneVmJob.php b/app/Jobs/Server/CloneVmJob.php new file mode 100644 index 00000000000..7eb0b0d0a11 --- /dev/null +++ b/app/Jobs/Server/CloneVmJob.php @@ -0,0 +1,48 @@ +step->deployment->server_id), + ]; + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function handle(VmSyncService $service): void + { + $this->step->run( + fn () => $service->handle($this->step->deployment->server), + ); + } +} diff --git a/app/Jobs/Server/DeleteServerJob.php b/app/Jobs/Server/DeleteServerJob.php deleted file mode 100644 index 1918889742e..00000000000 --- a/app/Jobs/Server/DeleteServerJob.php +++ /dev/null @@ -1,42 +0,0 @@ -serverId}", - )]; - } - - public function handle(ServerBuildService $service): void - { - $server = Server::findOrFail($this->serverId); - - $service->delete($server); - } -} diff --git a/app/Jobs/Server/DeleteVmJob.php b/app/Jobs/Server/DeleteVmJob.php new file mode 100644 index 00000000000..d1c8ed485f2 --- /dev/null +++ b/app/Jobs/Server/DeleteVmJob.php @@ -0,0 +1,75 @@ +addMinutes(30); + } + + public function middleware(): array + { + return [new SkipIfBatchCancelled]; + } + + public function __construct( + #[WithoutRelations] + public DeploymentStep $step, + ) {} + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function handle(ServerBuildService $service): void + { + $server = $this->step->deployment->server; + + try { + $this->step->kickOnce(fn () => $service->delete($server)); + } catch (RequestException $e) { + if (! $this->isNonexistentVMError($e)) { + throw $e; + } + + $this->logSwallowedNonexistentVM($server, 'delete'); + + // Already gone is already deleted. + $this->step->markCompleted(); + + return; + } + + if ($service->isVmDeleted($server)) { + $this->step->markCompleted(); + } else { + $this->release(3); + } + } +} diff --git a/app/Jobs/Server/FetchImageJob.php b/app/Jobs/Server/FetchImageJob.php new file mode 100644 index 00000000000..1f01fd9de93 --- /dev/null +++ b/app/Jobs/Server/FetchImageJob.php @@ -0,0 +1,100 @@ +addHours(3); + } + + public function middleware(): array + { + return [new SkipIfBatchCancelled]; + } + + public function __construct( + #[WithoutRelations] + public DeploymentStep $step, + ) {} + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function handle(ImageResidencyService $residency, ServerBuildService $build): void + { + $deployment = $this->step->deployment; + $node = $deployment->server->node; + $version = $deployment->imageVersion; + + if ($residency->isResident($node, $version)) { + $this->step->markCompleted(); + + return; + } + + // Both disks start downloading together; the system disk's task is the + // one worth watching, since the varstore beside it is a few hundred KiB. + $this->step->kickOnce( + fn () => Arr::first($residency->ensureResident($node, $version)) ?? '', + ); + + if (filled($this->step->task_upid)) { + try { + [$current, $total] = $build->getDownloadProgress($node, $this->step->task_upid); + + if ($total > 0) { + $this->step->update([ + 'progress_current' => min($current, $total), + 'progress_total' => $total, + ]); + } + } catch (Exception) { + // A log that cannot be read yet is not a failed download. + } + } + + $this->release(now()->addSeconds(2)); + } +} diff --git a/app/Jobs/Server/ImportVmJob.php b/app/Jobs/Server/ImportVmJob.php new file mode 100644 index 00000000000..62b263fa92b --- /dev/null +++ b/app/Jobs/Server/ImportVmJob.php @@ -0,0 +1,101 @@ +addMinutes(30); + } + + public function middleware(): array + { + return [new SkipIfBatchCancelled]; + } + + public function __construct( + #[WithoutRelations] + public DeploymentStep $step, + ) {} + + /** + * Resolved out of the container rather than injected, so the job stays + * serialisable: only the step is queued. + */ + private ImageResidencyService $residency; + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function handle(ServerBuildService $service, ImageResidencyService $residency): void + { + $this->residency = $residency; + + $deployment = $this->step->deployment; + $server = $deployment->server; + $version = $deployment->imageVersion; + + $this->step->kickOnce(fn () => $service->build( + $server, + $version, + $this->residency->volids($server->node, $version), + )); + + try { + [$current, $total] = $service->getImportProgress($server->node, $this->step->task_upid); + + // Proxmox's reported total is authoritative and stable across polls, + // so adopt it and clamp current to it — letting the total grow made + // the percentage jump backwards. The step's seeded size, taken from + // the image version rather than from a node, only gives the bar a + // scale before the first poll lands. + $this->step->update([ + 'progress_current' => min($current, $total), + 'progress_total' => $total, + ]); + } catch (Exception|NotFoundExceptionInterface|ContainerExceptionInterface) { + // The import task status is not always readable immediately; a + // failed read just means we poll again rather than fail the step. + } + + if ($service->isVmCreated($server)) { + $this->step->markCompleted(); + } else { + $this->release(now()->addMilliseconds(250)); + } + } +} diff --git a/app/Jobs/Server/MonitorBackupJob.php b/app/Jobs/Server/MonitorBackupJob.php index e68d56ca281..0254569ef9c 100644 --- a/app/Jobs/Server/MonitorBackupJob.php +++ b/app/Jobs/Server/MonitorBackupJob.php @@ -1,14 +1,20 @@ addDay(); } - public function __construct(protected int $backupId, protected string $upid) + public function __construct( + #[WithoutRelations] + public Backup $backup, + public string $upid + ) {} + + public function middleware(): array { + return [new ExpiringWithoutOverlapping((string) $this->backup->id)]; } - public function middleware(): array + public function handle(ProxmoxActivityClient $client, ProxmoxBackupClient $backupClient): void { - return [new WithoutOverlapping("server:backup.create#{$this->backupId}")]; + $task = $client->setServer($this->backup->server)->getStatus($this->upid); + + if ($task->status === TaskStatus::RUNNING) { + $this->release(3); + + return; + } + + $logs = $client->setServer($this->backup->server)->getLogsByTask($this->upid); + + // get the filename of the backup (e.g. vzdump-qemu-101-2021_01_01-00_00_00.vma.zstd) + $fileName = null; + foreach ($logs as $log) { + if (preg_match("/INFO: creating vzdump archive '(.+)'/s", $log->text, $matches)) { + $fileName = basename($matches[1]); + } + } + + if ($task->exitStatus === TaskExitStatus::OK) { + $archives = $backupClient->setServer($this->backup->server)->getBackups($this->backup->storage); + $archive = collect($archives)->firstWhere( + 'volumeId', + "{$this->backup->storage->name}:backup/{$fileName}", + ); + $archiveSize = $archive instanceof BackupData ? $archive->size : 0; + + $this->backup->update([ + 'file_name' => $fileName, + 'size' => $archiveSize, + 'completed_at' => Carbon::now(), + ]); + } else { + $errorMessage = $this->extractErrorMessage($logs) ?? $task->exitStatus->value; + + $this->backup->update([ + 'error_code' => BackupErrorCode::classify($errorMessage), + 'error_message' => $errorMessage, + 'completed_at' => Carbon::now(), + ]); + } } - public function handle(BackupMonitorService $service): void + /** + * Pull the first `ERROR:` line out of the vzdump task log, which carries the + * human-readable failure reason (e.g. "no space left on device"). + * + * @param iterable $logs + */ + private function extractErrorMessage(iterable $logs): ?string { - $backup = Backup::findOrFail($this->backupId); + foreach ($logs as $log) { + if (preg_match('/ERROR:\s*(.+)/', $log->text, $matches)) { + return trim($matches[1]); + } + } - $service->checkCreationProgress($backup, $this->upid, fn () => $this->release(3)); + return null; } } diff --git a/app/Jobs/Server/MonitorBackupRestorationJob.php b/app/Jobs/Server/MonitorBackupRestorationJob.php index 189a9789bcf..30de6999cb6 100644 --- a/app/Jobs/Server/MonitorBackupRestorationJob.php +++ b/app/Jobs/Server/MonitorBackupRestorationJob.php @@ -1,14 +1,17 @@ addDay(); } - public function __construct(protected int $serverId, protected string $upid) - { - } + public function __construct( + #[WithoutRelations] + public Server $server, + public string $upid + ) {} public function middleware(): array { - return [new WithoutOverlapping("server:backup.restore#{$this->serverId}")]; + return [new ExpiringWithoutOverlapping((string) $this->server->id)]; } - public function handle(BackupMonitorService $service): void + public function handle(ProxmoxActivityClient $client): void { - $server = Server::findOrFail($this->serverId); + $task = $client->setServer($this->server)->getStatus($this->upid); + + if ($task->status === TaskStatus::RUNNING) { + $this->release(3); + + return; + } - $service->checkRestorationProgress($server, $this->upid, fn () => $this->release(3)); + $this->server->update([ + 'lifecycle' => ServerLifecycle::READY, + ]); } } diff --git a/app/Jobs/Server/MonitorStateJob.php b/app/Jobs/Server/MonitorStateJob.php deleted file mode 100644 index 9375cc992d0..00000000000 --- a/app/Jobs/Server/MonitorStateJob.php +++ /dev/null @@ -1,55 +0,0 @@ -addMinutes(2); - } - - public function __construct( - protected int $serverId, - protected State $targetState, - protected ?Closure $callback = null, - ) - { - // - } - - public function middleware(): array - { - return [new SkipIfBatchCancelled()]; - } - - public function handle(ProxmoxServerRepository $repository): void - { - $server = Server::findOrFail($this->serverId); - - $stateData = $repository->setServer($server)->getState(); - - if ($stateData->state === $this->targetState) { - if ($this->callback !== null) { - call_user_func($this->callback); - } - } else { - $this->release(3); - } - } -} diff --git a/app/Jobs/Server/PurgeBackupsJob.php b/app/Jobs/Server/PurgeBackupsJob.php index 6d9a6bcbbf2..f9765df5ee0 100644 --- a/app/Jobs/Server/PurgeBackupsJob.php +++ b/app/Jobs/Server/PurgeBackupsJob.php @@ -1,42 +1,41 @@ serverId}", + return [new SkipIfBatchCancelled, new ExpiringWithoutOverlapping( + (string) $this->server->id, )]; } public function handle(PurgeBackupsService $service): void { - $server = Server::findOrFail($this->serverId); - - $service->handle($server); + $service->handle($this->server); } } diff --git a/app/Jobs/Server/SendPowerCommandJob.php b/app/Jobs/Server/SendPowerCommandJob.php index d63b5c78d7b..0638f64d8e3 100644 --- a/app/Jobs/Server/SendPowerCommandJob.php +++ b/app/Jobs/Server/SendPowerCommandJob.php @@ -1,42 +1,66 @@ serverId}", - )]; + return [ + new SkipIfBatchCancelled, + new ExpiringWithoutOverlapping((string) $this->step->deployment->server->id), + ]; } - public function handle(ProxmoxPowerRepository $repository): void + /** + * @throws RequestException|ConnectionException + */ + public function handle(ProxmoxPowerClient $client): void { - $server = Server::findOrFail($this->serverId); + $this->step->markRunning(); + + try { + $client->setServer($this->step->deployment->server)->send($this->power); + } catch (RequestException $e) { + // A VM that is already gone is a success for our purposes; any other + // provider error must propagate so the step is not marked complete. + if (! $this->isNonexistentVMError($e)) { + throw $e; + } + + $this->logSwallowedNonexistentVM($this->step->deployment->server, 'power command'); + } - $repository->setServer($server)->send($this->power); + // Reached only when the command succeeded (or the VM was already gone). + $this->step->markCompleted(); } } diff --git a/app/Jobs/Server/StopVmJob.php b/app/Jobs/Server/StopVmJob.php new file mode 100644 index 00000000000..eba244305d8 --- /dev/null +++ b/app/Jobs/Server/StopVmJob.php @@ -0,0 +1,80 @@ +addMinutes(2); + } + + public function middleware(): array + { + return [new SkipIfBatchCancelled]; + } + + public function __construct( + #[WithoutRelations] + public DeploymentStep $step, + ) {} + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function handle(ProxmoxPowerClient $power, ProxmoxServerClient $client): void + { + $server = $this->step->deployment->server; + + try { + $this->step->kickOnce(fn () => $power->setServer($server)->send(PowerCommand::KILL)); + + $state = $client->setServer($server)->getState(); + } catch (RequestException $e) { + if (! $this->isNonexistentVMError($e)) { + throw $e; + } + + $this->logSwallowedNonexistentVM($server, 'stop'); + + // Already gone is already stopped. + $this->step->markCompleted(); + + return; + } + + if ($state->powerState === PowerState::STOPPED) { + $this->step->markCompleted(); + } else { + $this->release(1); + } + } +} diff --git a/app/Jobs/Server/SyncBuildJob.php b/app/Jobs/Server/SyncBuildJob.php deleted file mode 100644 index a9f47bbc0e6..00000000000 --- a/app/Jobs/Server/SyncBuildJob.php +++ /dev/null @@ -1,42 +0,0 @@ -addMinutes(5); - } - - public function __construct(protected int $serverId) - { - } - - public function middleware(): array - { - return [new SkipIfBatchCancelled(), new WithoutOverlapping( - "server.sync#{$this->serverId}", - )]; - } - - public function handle(SyncBuildService $service): void - { - $server = Server::findOrFail($this->serverId); - - $service->handle($server); - } -} diff --git a/app/Jobs/Server/SyncNetworkSettings.php b/app/Jobs/Server/SyncNetworkSettings.php deleted file mode 100644 index ec30b39f00d..00000000000 --- a/app/Jobs/Server/SyncNetworkSettings.php +++ /dev/null @@ -1,42 +0,0 @@ -addMinutes(5); - } - - public function __construct(protected int $serverId) - { - } - - public function middleware(): array - { - return [new SkipIfBatchCancelled(), new WithoutOverlapping( - "server.sync-network-settings#$this->serverId", - )]; - } - - public function handle(NetworkService $service): void - { - $server = Server::findOrFail($this->serverId); - - $service->syncSettings($server); - } -} diff --git a/app/Jobs/Server/SyncNetworkSettingsJob.php b/app/Jobs/Server/SyncNetworkSettingsJob.php new file mode 100644 index 00000000000..434034a2592 --- /dev/null +++ b/app/Jobs/Server/SyncNetworkSettingsJob.php @@ -0,0 +1,44 @@ +server->id), + ]; + } + + /** + * @throws RequestException + */ + public function handle(ServerNetworkService $service): void + { + $service->syncSettings($this->server); + } +} diff --git a/app/Jobs/Server/SyncServerRateLimitJob.php b/app/Jobs/Server/SyncServerRateLimitJob.php new file mode 100644 index 00000000000..2309acd3cba --- /dev/null +++ b/app/Jobs/Server/SyncServerRateLimitJob.php @@ -0,0 +1,53 @@ +server->id), + ]; + } + + /** + * @throws RequestException + * @throws ConfigModifiedException + */ + public function handle(ServerRateLimitsSyncService $service): void + { + $service->sync($this->server); + } +} diff --git a/app/Jobs/Server/UpdatePasswordJob.php b/app/Jobs/Server/UpdatePasswordJob.php index 996580f2435..873a77fbef5 100644 --- a/app/Jobs/Server/UpdatePasswordJob.php +++ b/app/Jobs/Server/UpdatePasswordJob.php @@ -1,46 +1,47 @@ serverId}", - )]; + return [ + new SkipIfBatchCancelled, + new ExpiringWithoutOverlapping( + (string) $this->step->deployment->server->id + ), + ]; } public function handle(ServerAuthService $service): void { - $server = Server::findOrFail($this->serverId); - - $service->updatePassword($server, $this->password); + $this->step->run( + fn () => $service->setPassword($this->step->deployment->server, $this->password), + ); } } diff --git a/app/Jobs/Server/WaitUntilVmIsCreatedJob.php b/app/Jobs/Server/WaitUntilVmIsCreatedJob.php deleted file mode 100644 index 9f6d81076bf..00000000000 --- a/app/Jobs/Server/WaitUntilVmIsCreatedJob.php +++ /dev/null @@ -1,44 +0,0 @@ -addMinutes(30); - } - - public function middleware(): array - { - return [new SkipIfBatchCancelled()]; - } - - public function __construct(protected int $serverId) - { - // - } - - public function handle(ServerBuildService $service): void - { - $server = Server::findOrFail($this->serverId); - - $isCreated = $service->isVmCreated($server); - - if (!$isCreated) { - $this->release(3); - } - } -} diff --git a/app/Jobs/Server/WaitUntilVmIsDeletedJob.php b/app/Jobs/Server/WaitUntilVmIsDeletedJob.php deleted file mode 100644 index d8e3a890ebb..00000000000 --- a/app/Jobs/Server/WaitUntilVmIsDeletedJob.php +++ /dev/null @@ -1,44 +0,0 @@ -addMinutes(30); - } - - public function middleware(): array - { - return [new SkipIfBatchCancelled()]; - } - - public function __construct(protected int $serverId) - { - // - } - - public function handle(ServerBuildService $service): void - { - $server = Server::findOrFail($this->serverId); - - $isDeleted = $service->isVmDeleted($server); - - if (!$isDeleted) { - $this->release(3); - } - } -} diff --git a/app/Listeners/AuditAuthenticationSubscriber.php b/app/Listeners/AuditAuthenticationSubscriber.php new file mode 100644 index 00000000000..4667e4e623b --- /dev/null +++ b/app/Listeners/AuditAuthenticationSubscriber.php @@ -0,0 +1,103 @@ +user instanceof User ? $event->user : null, + properties: ['guard' => $event->guard, 'remember' => $event->remember], + actor: $event->user instanceof User ? $event->user : null, + ); + } + + public function onLogout(Logout $event): void + { + Audit::record( + AuditEvent::AUTH_LOGOUT, + subject: $event->user instanceof User ? $event->user : null, + properties: ['guard' => $event->guard], + actor: $event->user instanceof User ? $event->user : null, + ); + } + + public function onFailed(Failed $event): void + { + // The actor is deliberately left null — nobody authenticated. The attempted identifier is + // recorded instead, which is what makes a run of failures against one account legible. + // Never the supplied password, even though $event->credentials carries it. + Audit::record( + AuditEvent::AUTH_LOGIN_FAILED, + subject: $event->user instanceof User ? $event->user : null, + properties: [ + 'guard' => $event->guard, + 'email' => $event->credentials['email'] ?? null, + ], + ); + } + + public function onTwoFactorEnabled(TwoFactorAuthenticationEnabled $event): void + { + $this->recordTwoFactor(AuditEvent::ACCOUNT_TWO_FACTOR_ENABLED, $event->user); + } + + public function onTwoFactorConfirmed(TwoFactorAuthenticationConfirmed $event): void + { + $this->recordTwoFactor(AuditEvent::ACCOUNT_TWO_FACTOR_CONFIRMED, $event->user); + } + + public function onTwoFactorDisabled(TwoFactorAuthenticationDisabled $event): void + { + $this->recordTwoFactor(AuditEvent::ACCOUNT_TWO_FACTOR_DISABLED, $event->user); + } + + private function recordTwoFactor(AuditEvent $auditEvent, mixed $user): void + { + $user = $user instanceof User ? $user : null; + + // Subject is the account the factor belongs to; the actor falls back to whoever is + // authenticated, so an admin disabling a user's two-factor is recorded as two different + // people rather than as the user doing it to themselves. + Audit::record($auditEvent, subject: $user); + } + + public function subscribe(Dispatcher $events): array + { + return [ + Login::class => 'onLogin', + Logout::class => 'onLogout', + Failed::class => 'onFailed', + TwoFactorAuthenticationEnabled::class => 'onTwoFactorEnabled', + TwoFactorAuthenticationConfirmed::class => 'onTwoFactorConfirmed', + TwoFactorAuthenticationDisabled::class => 'onTwoFactorDisabled', + ]; + } +} diff --git a/app/Models/ActivityLog.php b/app/Models/ActivityLog.php deleted file mode 100644 index 591b1b0aefb..00000000000 --- a/app/Models/ActivityLog.php +++ /dev/null @@ -1,81 +0,0 @@ - 'collection', - 'timestamp' => 'datetime', - ]; - - protected $with = ['subjects']; - - public static array $validationRules = [ - 'event' => ['required', 'string'], - 'batch' => ['nullable', 'uuid'], - 'ip' => ['required', 'string'], - 'description' => ['nullable', 'string'], - 'properties' => ['array'], - ]; - - public function actor(): MorphTo - { - $morph = $this->morphTo(); - if (method_exists($morph, 'withTrashed')) { - return $morph->withTrashed(); - } - - return $morph; - } - - public function subjects(): HasMany - { - return $this->hasMany(ActivityLogSubject::class); - } - - public function scopeForEvent(Builder $builder, string $action): Builder - { - return $builder->where('event', $action); - } - - /** - * Scopes a query to only return results where the actor is a given model. - */ - public function scopeForActor(Builder $builder, Model $actor): Builder - { - return $builder->whereMorphedTo('actor', $actor); - } - - /** - * Returns models to be pruned. - * - * @see https://laravel.com/docs/9.x/eloquent#pruning-models - */ - public function prunable(): ActivityLog - { - if (is_null(config('activity.prune_days'))) { - throw new LogicException( - 'Cannot prune activity logs: no "prune_days" configuration value is set.', - ); - } - - return static::where( - 'created_at', '<=', Carbon::now()->subDays(config('activity.prune_days')), - ); - } -} diff --git a/app/Models/ActivityLogSubject.php b/app/Models/ActivityLogSubject.php deleted file mode 100644 index 4eb444f108e..00000000000 --- a/app/Models/ActivityLogSubject.php +++ /dev/null @@ -1,25 +0,0 @@ -belongsTo(ActivityLog::class); - } - - public function subject(): MorphTo - { - $morph = $this->morphTo(); - if (method_exists($morph, 'withTrashed')) { - return $morph->withTrashed(); - } - - return $morph; - } -} diff --git a/app/Models/Address.php b/app/Models/Address.php index 1fda6c7874c..cdb99b762a8 100644 --- a/app/Models/Address.php +++ b/app/Models/Address.php @@ -1,33 +1,141 @@ ['exists:address_pools,id', 'required'], + 'address_block_id' => ['exists:address_blocks,id', 'required'], 'server_id' => ['exists:servers,id', 'nullable'], - 'type' => ['in:ipv4,ipv6', 'required'], - 'address' => ['ip'], - 'cidr' => ['numeric', 'min:0', 'max:128', 'required'], - 'gateway' => ['ip'], - 'mac_address' => ['mac_address', 'nullable'], + 'ip' => ['ip'], + 'prefix_length' => ['numeric', 'min:0', 'max:128', 'required'], ]; + public function casts(): array + { + return [ + 'state' => AddressState::class, + 'state_reason' => AddressStateReason::class, + ]; + } + + /** + * @return BelongsTo + */ + public function addressBlock(): BelongsTo + { + return $this->belongsTo(AddressBlock::class); + } + + public function addressBlockGroup(): HasOneDeep + { + return $this->hasOneDeep( + AddressBlockGroup::class, + [AddressBlock::class], + [ + 'id', + 'id', + ], + [ + 'address_block_id', + 'address_block_group_id', + ]); + } + + public function networkInterfaces(): HasManyDeep + { + return $this->hasManyDeep( + NetworkInterface::class, + [AddressBlock::class, AddressBlockGroup::class, 'address_block_group_to_network_interface'], + [ + 'id', + 'id', + 'address_block_group_id', + 'id', + ], + [ + 'address_block_id', + 'address_block_group_id', + 'id', + null, + ] + ); + } + + /** + * @return BelongsTo + */ public function server(): BelongsTo { return $this->belongsTo(Server::class); } + /** Reserved by the panel because allocating it would break the subnet; operators can't free it. */ + public function isSystemReserved(): bool + { + return $this->state === AddressState::Reserved + && $this->state_reason === AddressStateReason::System; + } + + public function scopeWithIPv4(Builder $query): Builder + { + return $query->whereHas('addressBlock', function (Builder $query) { + $query->where('version', AddressVersion::IPv4); + }); + } + + public function scopeWithIPv6(Builder $query): Builder + { + return $query->whereHas('addressBlock', function (Builder $query) { + $query->where('version', AddressVersion::IPv6); + }); + } + + public function getVersionAttribute(): AddressVersion + { + return $this->addressBlock->version; + } + + public function getGatewayAttribute(): ?string + { + return $this->addressBlock->gateway; + } + + public function getMacAddressAttribute(): ?string + { + return $this->addressBlock->mac_address; + } + public function getRouteKeyName(): string { return 'id'; diff --git a/app/Models/AddressBlock.php b/app/Models/AddressBlock.php new file mode 100644 index 00000000000..20a2ef73fe8 --- /dev/null +++ b/app/Models/AddressBlock.php @@ -0,0 +1,302 @@ + $addresses + */ +class AddressBlock extends Model +{ + use CountsAddressStates; + + public $timestamps = false; + + /** `version` is derived from base_ip — a database-generated column that cannot be written to. */ + protected $guarded = ['id', 'version']; + + public static array $validationRules = [ + 'address_block_group_id' => 'required|integer|exists:address_block_groups,id', + 'name' => 'nullable|string|max:40', + 'description' => 'nullable|string|max:191', + 'base_ip' => 'required|ip', + 'gateway' => 'nullable|ip', + 'mac_address' => 'nullable|mac_address', + 'prefix_length_from' => 'required|integer|min:0|max:128', + 'prefix_length_to' => 'required|integer|min:0|max:128', + ]; + + /** + * Read from base_ip rather than the column so an unsaved block — the geometry validator builds + * one to test a submitted block before it exists — answers the same as a persisted one. The + * column is the database's own copy of this derivation and is only there for SQL filters. + */ + protected function version(): Attribute + { + return Attribute::get(function (?string $stored): AddressVersion { + $baseIp = $this->attributes['base_ip'] ?? null; + + // base_ip wasn't selected; fall back to the generated column, which cannot disagree. + if ($baseIp === null) { + return AddressVersion::from((string) $stored); + } + + return str_contains($baseIp, ':') ? AddressVersion::IPv6 : AddressVersion::IPv4; + }); + } + + /** + * @return BelongsTo + */ + public function addressBlockGroup(): BelongsTo + { + return $this->belongsTo(AddressBlockGroup::class); + } + + /** + * @return HasMany + */ + public function addresses(): HasMany + { + return $this->hasMany(Address::class); + } + + public function getRouteKeyName(): string + { + return 'id'; + } + + /** + * Blocks with more allocatable units than this are stored *sparsely* — their addresses are + * minted on demand by the allocator instead of being pre-materialized, since a large v4 block + * (or any v6 block) would be billions of rows. See AddressAllocationService / GenerateAddressesAction. + */ + public const DENSE_MAX_HOST_BITS = 16; // 2^16 = 65,536 units materialized at most + + public function maxPrefixLength(): int + { + return $this->version === AddressVersion::IPv4 ? 32 : 128; + } + + /** Number of allocatable units = 2^(prefix_to - prefix_from). */ + public function allocatableHostBits(): int + { + return $this->prefix_length_to - $this->prefix_length_from; + } + + public function isSparse(): bool + { + return $this->allocatableHostBits() > self::DENSE_MAX_HOST_BITS; + } + + /** + * How many units this block can ever hand out, or null when that count is not representable. + * + * A sparse block's 2^n runs past a PHP int (a /64 delegating /128s is 2^64) and is never + * materialized anyway, so there is no denominator to report — null says "unknown", which is + * different from a total of zero and has to stay different all the way to the meter. + */ + public function totalUnits(): ?int + { + return $this->isSparse() ? null : 1 << $this->allocatableHostBits(); + } + + /** + * The address distance between consecutive allocatable units (1 for individual addresses, + * 2^(maxbits - prefix_to) for sub-blocks). Kept within bigint so Postgres inet arithmetic works. + */ + public function unitStride(): int + { + $exponent = $this->maxPrefixLength() - $this->prefix_length_to; + + if ($exponent < 0 || $exponent > 62) { + throw new \RuntimeException("Address block {$this->id} has an unsupported unit stride (2^{$exponent})."); + } + + return 1 << $exponent; + } + + /** The first address of the block's overall range — its network address for v4. */ + public function firstAllocatableAddress(): string + { + return $this->blockRange()->getStartAddress()->toString(); + } + + /** The last address of the block's overall range (its broadcast for v4), the ceiling for minting. */ + public function lastAllocatableAddress(): string + { + return $this->blockRange()->getEndAddress()->toString(); + } + + /** + * Where $ip sits in the block's run of allocatable units, counting from zero. + * + * This is what lets the address map place a materialized address on the grid without + * re-deriving the whole unit sequence: generation writes units in address order, but a + * deletion leaves a hole, so position cannot be inferred from row order. GMP because a v6 + * offset does not fit in a PHP int even when the index does. + * + * Null when $ip is outside the block, or its index is past what an int can hold. + */ + public function unitIndexOf(string $ip): ?int + { + $start = inet_pton($this->firstAllocatableAddress()); + $target = inet_pton($ip); + + if ($start === false || $target === false || strlen($start) !== strlen($target)) { + return null; + } + + $offset = gmp_sub(gmp_import($target), gmp_import($start)); + + if (gmp_sign($offset) < 0) { + return null; + } + + $index = gmp_div_q($offset, gmp_init((string) $this->unitStride())); + + return gmp_cmp($index, gmp_init((string) PHP_INT_MAX)) > 0 + ? null + : gmp_intval($index); + } + + /** + * The address of the unit at $index, whether or not a row exists for it. + * + * The inverse of `unitIndexOf`. The map needs this because a unit is a real position in the + * block before anything is generated into it: without an address, an ungenerated cell can only + * be labelled by its offset, and "#32" tells an operator nothing they can act on. + */ + public function unitAddressAt(int $index): ?string + { + $start = inet_pton($this->firstAllocatableAddress()); + + if ($start === false || $index < 0) { + return null; + } + + $value = gmp_add( + gmp_import($start), + gmp_mul(gmp_init((string) $index), gmp_init((string) $this->unitStride())), + ); + + // gmp_export drops leading zero bytes (and returns '' for zero), so pad back to the + // address width; anything wider has run past the family and is not an address. + $bytes = str_pad(gmp_export($value), strlen($start), "\0", STR_PAD_LEFT); + + if (strlen($bytes) !== strlen($start)) { + return null; + } + + $ip = inet_ntop($bytes); + + return $ip === false ? null : $ip; + } + + /** + * The allocatable unit containing $ip — that is, $ip masked down to the block's output prefix. + * When the block hands out individual addresses (/32, /128) every unit is one address and this + * is the identity; when it delegates sub-blocks it answers "which sub-block owns this address". + */ + public function unitContaining(string $ip): ?string + { + return IPFactory::parseRangeString($ip.'/'.$this->prefix_length_to) + ?->getStartAddress() + ->toString(); + } + + public function containsAddress(string $ip): bool + { + $address = IPFactory::parseAddressString($ip); + + return $address !== null && $this->blockRange()->contains($address); + } + + /** + * Addresses that must never be handed to a VM and are auto-reserved. Returned at *unit* + * granularity — generation and minting only ever materialize unit boundaries, so a reservation + * that isn't itself a unit address silently matches nothing. + * + * Which addresses qualify depends on what a unit means for this block: + * + * - **Host allocation** (output prefix /32 or /128): units are individual addresses on a + * shared segment, so that segment's network, broadcast and subnet-router anycast are real + * hazards and are withheld. + * - **Subnet delegation** (output prefix shorter than a single address): each unit is a routed + * prefix whose holder manages its own network and broadcast internally, so the parent's are + * not ours to withhold — withholding them would lock a /24 → /24 block entirely. + * + * The gateway is a hazard under both: it lives inside exactly one unit, and handing that unit + * over hands over the gateway with it. + * + * @return list + */ + public function systemReservedAddresses(): array + { + $reserved = []; + + if ($this->prefix_length_to === $this->maxPrefixLength()) { + if ($this->version === AddressVersion::IPv4) { + // RFC 3021: a /31 point-to-point link has neither a network nor a broadcast address. + if ($this->prefix_length_from <= 30) { + $reserved[] = $this->firstAllocatableAddress(); // network + $reserved[] = $this->lastAllocatableAddress(); // broadcast + } + } else { + $reserved[] = $this->firstAllocatableAddress(); // subnet-router anycast + } + } + + // A gateway outside the block (an upstream router on a different prefix) owns no unit here, + // so masking it would invent a reservation for an address this block never hands out. + if ($this->gateway && $this->containsAddress($this->gateway)) { + $gatewayUnit = $this->unitContaining($this->gateway); + + if ($gatewayUnit !== null) { + $reserved[] = $gatewayUnit; + } + } + + return array_values(array_unique($reserved)); + } + + private function blockRange(): RangeInterface + { + $range = IPFactory::parseRangeString($this->base_ip.'/'.$this->prefix_length_from); + + if ($range === null) { + throw new \RuntimeException("Address block {$this->id} has an unparseable range ({$this->base_ip}/{$this->prefix_length_from})."); + } + + return $range; + } + + protected function macAddress(): Attribute + { + return Attribute::make( + get: fn (?string $value) => $value ? Str::lower($value) : null, + set: fn (?string $value) => $value ? Str::lower($value) : null, + ); + } +} diff --git a/app/Models/AddressBlockGroup.php b/app/Models/AddressBlockGroup.php new file mode 100644 index 00000000000..f33ef39fc98 --- /dev/null +++ b/app/Models/AddressBlockGroup.php @@ -0,0 +1,102 @@ + $addressBlocks + */ +class AddressBlockGroup extends Model +{ + use CountsAddressStates, HasFactory, HasRelationships; + + public $timestamps = false; + + protected $guarded = ['id']; + + public static array $validationRules = [ + 'name' => 'required|string|max:40', + 'description' => 'nullable|string|max:191', + ]; + + /** + * Gets the nodes that this address block group is connected to via network interfaces. + */ + public function nodes(): HasManyDeep + { + return $this->hasManyDeep( + Node::class, + ['address_block_group_to_network_interface', NetworkInterface::class], + [ + 'address_block_group_id', // Foreign key on the pivot table + 'id', // Foreign key on the network_interfaces table + 'id', // Local key on the nodes table + ], + [ + 'id', // Local key on the address_block_groups table + 'network_interface_id', // Foreign key on the pivot table + 'node_id', // Foreign key on the network_interfaces table + ] + ); + } + + /** + * @return HasMany + */ + public function addressBlocks(): HasMany + { + return $this->hasMany(AddressBlock::class); + } + + /** + * Every address under the pool, through its blocks. + * + * Only used for counting: it lets a page of pools carry its capacity in the same query as the + * rows, rather than one round trip per pool to add up its blocks. + * + * @return HasManyThrough + */ + public function addresses(): HasManyThrough + { + return $this->hasManyThrough( + Address::class, + AddressBlock::class, + 'address_block_group_id', + 'address_block_id', + 'id', + 'id', + ); + } + + /** + * Gets the network interfaces this address block group is allocated to. + */ + public function networkInterfaces(): BelongsToMany + { + return $this->belongsToMany( + NetworkInterface::class, + 'address_block_group_to_network_interface', + 'address_block_group_id', + 'network_interface_id' + ); + } + + /** + * The column Laravel should look at for route model binding. + */ + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/AddressBlockGroupToInterface.php b/app/Models/AddressBlockGroupToInterface.php new file mode 100644 index 00000000000..1d6fdeee77d --- /dev/null +++ b/app/Models/AddressBlockGroupToInterface.php @@ -0,0 +1,35 @@ +belongsTo(AddressBlockGroup::class); + } + + public function addresses(): HasManyThrough + { + return $this->hasManyThrough(Address::class, AddressBlockGroup::class); + } +} diff --git a/app/Models/AddressPool.php b/app/Models/AddressPool.php deleted file mode 100644 index 67ebbc789d5..00000000000 --- a/app/Models/AddressPool.php +++ /dev/null @@ -1,44 +0,0 @@ - 'required|string|max:191', - ]; - - /** - * Gets the nodes that an address pool is allocated to. - */ - public function nodes(): BelongsToMany - { - return $this->belongsToMany( - Node::class, 'address_pool_to_node', 'address_pool_id', 'node_id', - ); - } - - /** - * Gets the addresses that are associated with an address pool. - */ - public function addresses(): HasMany - { - return $this->hasMany(Address::class); - } - - /** - * The column Laravel should look at for route model binding. - */ - public function getRouteKeyName(): string - { - return 'id'; - } -} diff --git a/app/Models/AddressPoolToNode.php b/app/Models/AddressPoolToNode.php deleted file mode 100644 index cdfd793dcf9..00000000000 --- a/app/Models/AddressPoolToNode.php +++ /dev/null @@ -1,39 +0,0 @@ -belongsTo(AddressPool::class); - } - - public function node(): BelongsTo - { - return $this->belongsTo(Node::class); - } - - public function addresses(): HasManyThrough - { - return $this->hasManyThrough(Address::class, AddressPool::class); - } -} diff --git a/app/Models/AnchorEnrollment.php b/app/Models/AnchorEnrollment.php new file mode 100644 index 00000000000..667d27f5b98 --- /dev/null +++ b/app/Models/AnchorEnrollment.php @@ -0,0 +1,154 @@ +|null $reported_facts + * @property Carbon|null $enrolled_at + * @property Carbon|null $last_seen_at + * @property string|null $version + * @property int|null $protocol_min + * @property int|null $protocol_max + * @property array|null $capabilities + */ +class AnchorEnrollment extends Model +{ + use AnchorInstallation, HasFactory; + + protected $guarded = ['id', 'created_at', 'updated_at']; + + protected $hidden = ['secret']; + + public static array $validationRules = [ + 'uuid' => 'required|uuid', + 'name' => 'required|string|max:191', + 'mode' => 'required|string|in:agent,relay', + 'secret' => 'required|string|min:32', + 'enrollment_key_id' => 'nullable|integer|exists:anchor_enrollment_keys,id', + 'reported_facts' => 'nullable|array', + 'enrolled_at' => 'nullable|date', + 'last_seen_at' => 'nullable|date', + 'version' => 'nullable|string|max:191', + 'protocol_min' => 'nullable|integer|min:1', + 'protocol_max' => 'nullable|integer|min:1', + 'capabilities' => 'nullable|array', + ]; + + protected function casts(): array + { + return [ + 'mode' => AnchorMode::class, + 'secret' => 'encrypted', + 'enrolled_at' => 'datetime', + 'last_seen_at' => 'datetime', + 'protocol_min' => 'integer', + 'protocol_max' => 'integer', + 'capabilities' => 'array', + 'reported_facts' => 'array', + ]; + } + + /** @return BelongsTo */ + public function enrollmentKey(): BelongsTo + { + return $this->belongsTo(AnchorEnrollmentKey::class, 'enrollment_key_id'); + } + + /** Whatever the machine said about itself, or null if it said nothing. */ + public function reported(string $key): mixed + { + return $this->reported_facts[$key] ?? null; + } + + public function anchorName(): string + { + return $this->name; + } + + public function anchorUuid(): ?string + { + return $this->uuid; + } + + public function anchorSecret(): ?string + { + return $this->secret; + } + + public function anchorEnrolledAt(): ?Carbon + { + return $this->enrolled_at; + } + + public function anchorLastSeenAt(): ?Carbon + { + return $this->last_seen_at; + } + + public function anchorProtocolMin(): ?int + { + return $this->protocol_min; + } + + public function anchorProtocolMax(): ?int + { + return $this->protocol_max; + } + + /** Nobody has established one yet; that is what approval is for. */ + public function anchorPublicUrl(): ?string + { + return null; + } + + public function anchorPanelUrlOverride(): ?string + { + return null; + } + + public function anchorMode(): AnchorMode + { + return $this->mode; + } + + /** @param array $payload */ + public function recordAnchorHeartbeat(array $payload): void + { + $this->update([ + 'last_seen_at' => now(), + 'version' => $payload['version'], + 'protocol_min' => $payload['protocol_min'], + 'protocol_max' => $payload['protocol_max'], + 'capabilities' => $payload['capabilities'], + ]); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/AnchorEnrollmentKey.php b/app/Models/AnchorEnrollmentKey.php new file mode 100644 index 00000000000..fcb1bd038b1 --- /dev/null +++ b/app/Models/AnchorEnrollmentKey.php @@ -0,0 +1,125 @@ + 'required|uuid', + 'name' => 'required|string|max:191', + 'token_hash' => 'required|string|size:64', + 'mode' => 'nullable|string|in:agent,relay', + 'max_uses' => 'nullable|integer|min:1', + 'uses' => 'required|integer|min:0', + 'expires_at' => 'nullable|date', + 'revoked_at' => 'nullable|date', + 'last_used_at' => 'nullable|date', + 'created_by' => 'nullable|integer|exists:users,id', + ]; + + protected function casts(): array + { + return [ + 'mode' => AnchorMode::class, + 'max_uses' => 'integer', + 'uses' => 'integer', + 'expires_at' => 'datetime', + 'revoked_at' => 'datetime', + 'last_used_at' => 'datetime', + ]; + } + + /** @return BelongsTo */ + public function createdBy(): BelongsTo + { + return $this->belongsTo(User::class, 'created_by'); + } + + public function status(): EnrollmentKeyStatus + { + return match (true) { + $this->revoked_at !== null => EnrollmentKeyStatus::REVOKED, + $this->expires_at?->isPast() === true => EnrollmentKeyStatus::EXPIRED, + $this->max_uses !== null && $this->uses >= $this->max_uses => EnrollmentKeyStatus::EXHAUSTED, + default => EnrollmentKeyStatus::ACTIVE, + }; + } + + public function isUsable(): bool + { + return $this->status() === EnrollmentKeyStatus::ACTIVE; + } + + /** + * Whether this key permits an installation claiming `$mode`. + * + * A null `mode` on the key means "either", which is why this cannot be + * written as a plain equality check at the call site. + */ + public function permits(AnchorMode $mode): bool + { + return $this->mode === null || $this->mode === $mode; + } + + /** + * The same question {@see status()} answers, pushed into SQL so a roster + * can filter without hydrating every row. + * + * Kept beside `status()` rather than in a query-builder class precisely + * because the two must agree; separating them is how they drift. + * + * @param Builder $query + */ + public function scopeUsable(Builder $query): void + { + $query->whereNull('revoked_at') + ->where(fn (Builder $query) => $query + ->whereNull('expires_at') + ->orWhere('expires_at', '>', now())) + ->where(fn (Builder $query) => $query + ->whereNull('max_uses') + ->orWhereColumn('uses', '<', 'max_uses')); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/AuditLog.php b/app/Models/AuditLog.php new file mode 100644 index 00000000000..e8271783f16 --- /dev/null +++ b/app/Models/AuditLog.php @@ -0,0 +1,108 @@ + AuditEvent::class, + 'properties' => 'collection', + 'created_at' => 'immutable_datetime', + ]; + } + + /** + * Who acted. A {@see User} for anything a person did, a {@see SystemActor} for panel-wide + * application tokens, and null only when the action could not be attributed at all. + * + * The relation resolves to null once the actor is deleted — nothing in this panel soft-deletes + * — so read {@see $actor_label} for display and treat this relation as "the actor, if they + * still exist". + */ + public function actor(): MorphTo + { + return $this->morphTo(); + } + + /** What was acted on — a Server, Node, User, token, or whatever else the event concerns. */ + public function subject(): MorphTo + { + return $this->morphTo(); + } + + /** The API token used, when the action arrived over the API rather than a browser session. */ + public function apiToken(): BelongsTo + { + return $this->belongsTo(PersonalAccessToken::class, 'api_token_id'); + } + + public function scopeForEvent(Builder $builder, AuditEvent $event): Builder + { + return $builder->where('event', $event->value); + } + + public function scopeForActor(Builder $builder, Model $actor): Builder + { + return $builder->whereMorphedTo('actor', $actor); + } + + public function scopeForSubject(Builder $builder, Model $subject): Builder + { + return $builder->whereMorphedTo('subject', $subject); + } + + /** + * Restricts a query to the events a non-admin is allowed to see. Applied on top of whatever + * subject scoping the caller has already done — this filters by event *kind*, not by ownership. + */ + public function scopeClientVisible(Builder $builder): Builder + { + $hidden = array_map( + fn (AuditEvent $event) => $event->value, + array_values(array_filter( + AuditEvent::cases(), + fn (AuditEvent $event) => $event->visibility() === AuditVisibility::ADMIN_ONLY, + )), + ); + + return $hidden === [] ? $builder : $builder->whereNotIn('event', $hidden); + } +} diff --git a/app/Models/Backup.php b/app/Models/Backup.php index b8098a21bd8..c11cfcd0bdb 100644 --- a/app/Models/Backup.php +++ b/app/Models/Backup.php @@ -1,36 +1,103 @@ 'datetime', - 'size' => MebibytesToAndFromBytes::class, - ]; + protected $guarded = ['id', 'created_at', 'updated_at']; public static array $validationRules = [ 'uuid' => 'required|uuid', - 'server_id' => 'required|exists:servers,id', - 'is_successful' => 'sometimes|boolean', + 'server_id' => 'required|integer|exists:servers,id', + 'storage_id' => 'required|integer|exists:storages,id', 'is_locked' => 'sometimes|boolean', 'name' => 'required|string|min:1|max:40', 'file_name' => 'nullable|string', - 'size' => 'sometimes|numeric|min:0', + 'size' => 'nullable|numeric|min:0', 'completed_at' => 'nullable|date', ]; + protected function casts(): array + { + return [ + 'completed_at' => 'datetime', + 'size' => StorageSizeCast::class, + 'error_code' => BackupErrorCode::class, + ]; + } + + /** + * @return BelongsTo + */ public function server(): BelongsTo { return $this->belongsTo(Server::class); } + + /** + * @return BelongsTo + */ + public function storage(): BelongsTo + { + return $this->belongsTo(Storage::class); + } + + public function scopeSuccessful(Builder $query): void + { + $query->whereNull('error_code') + ->whereNotNull('completed_at'); + } + + public function scopeRunning(Builder $query): void + { + $query->whereNull('completed_at'); + } + + /** + * Backups that have not failed: still running, or finished without an error. + * + * Grouped so the OR cannot leak out and widen a caller's other constraints. + */ + public function scopeNonFailed(Builder $query): void + { + $query->where(function (Builder $query) { + $query->whereNull('completed_at') + ->orWhereNull('error_code'); + }); + } + + /** + * Backups created within the last $seconds (creation throttling). + */ + public function scopeCreatedWithinSeconds(Builder $query, int $seconds): void + { + $query->where('created_at', '>=', now()->subSeconds($seconds)); + } } diff --git a/app/Models/Cluster.php b/app/Models/Cluster.php new file mode 100644 index 00000000000..1b0185bef6a --- /dev/null +++ b/app/Models/Cluster.php @@ -0,0 +1,69 @@ + $member_names + * @property ?CarbonImmutable $flagged_at + * @property ?string $flag_reason + */ +class Cluster extends Model +{ + use HasFactory; + + protected $guarded = ['id']; + + protected function casts(): array + { + return [ + 'member_names' => 'array', + 'flagged_at' => 'immutable_datetime', + ]; + } + + /** + * @return HasMany + */ + public function nodes(): HasMany + { + return $this->hasMany(Node::class); + } + + /** + * @return HasMany + */ + public function storages(): HasMany + { + return $this->hasMany(Storage::class); + } + + public function isStandalone(): bool + { + return $this->fingerprint === null; + } + + /** + * The column Laravel should look at for route model binding. The base + * model says `uuid`, which clusters do not have. + */ + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/Concerns/AnchorInstallation.php b/app/Models/Concerns/AnchorInstallation.php new file mode 100644 index 00000000000..1df01140eae --- /dev/null +++ b/app/Models/Concerns/AnchorInstallation.php @@ -0,0 +1,124 @@ + $payload + */ + abstract public function recordAnchorHeartbeat(array $payload): void; + + public function anchorCompatibility(): AnchorCompatibility + { + if ($this->anchorUuid() === null || $this->anchorEnrolledAt() === null) { + return AnchorCompatibility::UNENROLLED; + } + + $lastSeen = $this->anchorLastSeenAt(); + + if ($lastSeen === null || $lastSeen->lt(now()->subMinutes(AnchorProtocol::STATUS_TTL_MINUTES))) { + return AnchorCompatibility::OFFLINE; + } + + $min = $this->anchorProtocolMin(); + $max = $this->anchorProtocolMax(); + + if ($min === null || $max === null || $min > AnchorProtocol::VERSION || $max < AnchorProtocol::VERSION) { + return AnchorCompatibility::INCOMPATIBLE; + } + + return AnchorCompatibility::COMPATIBLE; + } + + public function hasAnchor(): bool + { + return $this->anchorUuid() !== null; + } + + /** + * Where this installation should reach the panel. + * + * The reverse of the public URL: an installation may sit on a network where + * the panel's canonical address does not resolve (a private tunnel, a split + * DNS horizon), so it can be pointed at one that does. Cascades its own + * override over the panel-wide default, because a fleet usually shares one + * such address and only occasionally needs them to differ. + */ + public function anchorPanelUrl(): string + { + $override = $this->anchorPanelUrlOverride(); + + return $override + ? rtrim($override, '/') + : app(AnchorSettings::class)->resolvedPanelUrl(); + } + + /** + * Null when nobody has established how the panel reaches this installation. + * + * Returned rather than asserted away: a console that declines with a + * sentence is recoverable, and a TypeError inside token issuance is not. + */ + public function anchorWebsocketUrl(): ?string + { + $public = $this->anchorPublicUrl(); + + if ($public === null) { + return null; + } + + $url = rtrim($public, '/').'/api/v1/console'; + + return preg_replace('/^http/i', 'ws', $url) ?? $url; + } +} diff --git a/app/Models/Concerns/CountsAddressStates.php b/app/Models/Concerns/CountsAddressStates.php new file mode 100644 index 00000000000..d5b3df0bd95 --- /dev/null +++ b/app/Models/Concerns/CountsAddressStates.php @@ -0,0 +1,67 @@ + + */ + public static function addressStateCounts(bool $denseOnly = false): array + { + $scope = fn (Builder $query) => $denseOnly + ? $query->whereRaw( + 'address_blocks.prefix_length_to - address_blocks.prefix_length_from <= ?', + [AddressBlock::DENSE_MAX_HOST_BITS], + ) + : $query; + + return [ + 'addresses' => fn (Builder $query) => $scope($query), + 'addresses as assigned_addresses_count' => fn (Builder $query) => $scope($query) + ->where('state', AddressState::Assigned), + 'addresses as reserved_addresses_count' => fn (Builder $query) => $scope($query) + ->where('state', AddressState::Reserved) + ->where(fn (Builder $inner) => $inner + ->whereNull('state_reason') + ->orWhere('state_reason', '!=', AddressStateReason::System)), + 'addresses as system_addresses_count' => fn (Builder $query) => $scope($query) + ->where('state', AddressState::Reserved) + ->where('state_reason', AddressStateReason::System), + 'addresses as available_addresses_count' => fn (Builder $query) => $scope($query) + ->where('state', AddressState::Available), + ]; + } + + /** + * @param Builder $query + */ + public function scopeWithAddressStateCounts(Builder $query, bool $denseOnly = false): void + { + $query->withCount(static::addressStateCounts($denseOnly)); + } +} diff --git a/app/Models/Coterm.php b/app/Models/Coterm.php deleted file mode 100644 index 968ca027db1..00000000000 --- a/app/Models/Coterm.php +++ /dev/null @@ -1,50 +0,0 @@ - 'boolean', - 'coterm_token' => NullableEncrypter::class, - ]; - - public static array $validationRules = [ - 'name' => 'required|string|max:191', - 'is_tls_enabled' => 'required|boolean', - 'fqdn' => 'required|string|max:191', - 'port' => 'required|integer|min:1|max:65535', - 'token_id' => 'required|string|max:191', - 'token' => 'required|string|max:191', - ]; - - public function nodes(): HasMany - { - return $this->hasMany(Node::class); - } - - public function getRouteKeyName(): string - { - return 'id'; - } -} diff --git a/app/Models/Deployment.php b/app/Models/Deployment.php new file mode 100644 index 00000000000..a3169ebd070 --- /dev/null +++ b/app/Models/Deployment.php @@ -0,0 +1,135 @@ + + */ + protected $guarded = [ + 'id', + ]; + + /** + * Rules ensuring that the raw data stored in the database meets expectations. + */ + public static array $validationRules = [ + 'server_id' => 'required|exists:servers,id', + 'image_definition_id' => 'nullable|exists:image_definitions,id', + 'image_version_id' => 'nullable|exists:image_versions,id', + 'type' => 'required|string|in:install,reinstall,delete,import', + 'status' => 'required|string|in:pending,running,completed,failed', + 'start_on_completion' => 'required|boolean', + 'requested_at' => 'required|date', + 'started_at' => 'nullable|date', + 'completed_at' => 'nullable|date', + ]; + + public function casts(): array + { + return [ + 'type' => DeploymentType::class, + 'status' => DeploymentStatus::class, + 'should_create_vm' => 'boolean', + 'start_on_completion' => 'boolean', + 'requested_at' => 'datetime', + 'started_at' => 'datetime', + 'completed_at' => 'datetime', + ]; + } + + /** + * @return BelongsTo + */ + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + /** + * What was chosen. Kept beside the version so a deployment still says which + * image an operator picked even after that image is rebuilt or retired. + * + * @return BelongsTo + */ + public function imageDefinition(): BelongsTo + { + return $this->belongsTo(ImageDefinition::class); + } + + /** + * What was actually built. The disks and hashes this server came from. + * + * @return BelongsTo + */ + public function imageVersion(): BelongsTo + { + return $this->belongsTo(ImageVersion::class); + } + + /** + * @return HasMany + */ + public function steps(): HasMany + { + return $this->hasMany(DeploymentStep::class) + ->orderBy('sequence') + ->orderBy('id'); + } + + /** + * Create steps, stamping each with the next sequence number so their display + * order is explicit and stays correct even when steps are added by more than + * one action (a reinstall appends build steps after delete steps). + * + * @param array> $rows + * @return Collection + */ + public function addSteps(array $rows): Collection + { + $rows = array_values($rows); + $next = (int) $this->steps()->max('sequence'); + + foreach ($rows as $i => $row) { + $rows[$i]['sequence'] = $next + $i + 1; + } + + return $this->steps()->createMany($rows); + } + + public function scopeNonCompleted(Builder $query): void + { + $query->whereIn('status', [DeploymentStatus::PENDING, DeploymentStatus::RUNNING]); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/DeploymentStep.php b/app/Models/DeploymentStep.php new file mode 100644 index 00000000000..ae9681275ed --- /dev/null +++ b/app/Models/DeploymentStep.php @@ -0,0 +1,169 @@ + + */ + protected $guarded = [ + 'id', + ]; + + /** + * Rules ensuring that the raw data stored in the database meets expectations. + */ + public static array $validationRules = [ + 'deployment_id' => 'required|exists:deployments,id', + 'name' => 'required|string|max:191', + 'status' => 'required|string|in:running,completed,failed', + 'progress_mode' => 'required|string|in:determinate,indeterminate', + 'sequence' => 'required|integer|min:0', + 'task_upid' => 'nullable|string|max:191', + 'progress_total' => 'nullable|integer|min:0', + 'progress_current' => 'nullable|integer|min:0', + 'started_at' => 'nullable|date', + 'completed_at' => 'nullable|date', + 'error_code' => 'nullable|string|max:191', + 'error_message' => 'nullable|string|max:191', + ]; + + public function casts(): array + { + return [ + 'status' => DeploymentStatus::class, + 'progress_mode' => ProgressMode::class, + 'started_at' => 'datetime', + 'completed_at' => 'datetime', + ]; + } + + /** + * The only three ways a step's status may change. Each is a guarded + * transition — an illegal or repeated call is a silent no-op, never a + * corruption — so a job cannot flip a failed step to completed, a retry + * cannot reset the clock, and a late write cannot un-finish a step. + * + * `run()` composes these into the common "do work, then done" shape so a + * one-shot job can never forget to close its step. Steps whose work spans + * several queued jobs (kick then poll) call the transitions directly. + */ + public function markRunning(): void + { + // Idempotent: a retried job re-enters here, but we keep the original + // started_at rather than resetting it on every attempt. + if ($this->status !== DeploymentStatus::PENDING) { + return; + } + + $this->update([ + 'status' => DeploymentStatus::RUNNING, + 'started_at' => now(), + ]); + } + + public function markCompleted(): void + { + if ($this->status->isTerminal()) { + return; + } + + $this->update([ + 'status' => DeploymentStatus::COMPLETED, + 'completed_at' => now(), + ]); + } + + public function markFailed(?Throwable $exception = null): void + { + // A completed step stays completed; only a non-completed step can fail. + if ($this->status === DeploymentStatus::COMPLETED) { + return; + } + + $this->update([ + 'status' => DeploymentStatus::FAILED, + 'completed_at' => now(), + // error_message is capped at 191 chars in the schema; a raw + // provider message can be far longer and would blow up the write. + 'error_message' => Str::limit($exception?->getMessage() ?? 'Unknown error', 188), + ]); + } + + /** + * Start this step's asynchronous remote task exactly once, then remember its + * UPID. A single job both starts the task and polls it to completion by + * releasing itself back onto the queue; on every run after the first — + * retried or released — task_upid is already set, so the callback is + * skipped and the command is never issued twice. This is the durable guard + * that lets one job own a step whose work spans many invocations. + */ + public function kickOnce(callable $kick): void + { + if ($this->task_upid !== null) { + return; + } + + $this->markRunning(); + + $this->update(['task_upid' => $kick()]); + } + + /** + * Run one-shot work as this step: mark it running, do the work, and mark it + * completed — but only if the work returns without throwing. A throw skips + * completion and propagates, so Laravel retries the job and the step stays + * RUNNING; the terminal FAILED write happens once, in the job's `failed()` + * hook, after retries are exhausted. Completion is therefore tied to + * success and can never be left dangling. + */ + public function run(callable $work): void + { + $this->markRunning(); + + $work($this); + + $this->markCompleted(); + } + + /** + * @return BelongsTo + */ + public function deployment(): BelongsTo + { + return $this->belongsTo(Deployment::class); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/Filters/FiltersAddressBlockGroupWildcard.php b/app/Models/Filters/FiltersAddressBlockGroupWildcard.php new file mode 100644 index 00000000000..fad6200e71e --- /dev/null +++ b/app/Models/Filters/FiltersAddressBlockGroupWildcard.php @@ -0,0 +1,21 @@ +where(function (Builder $query) use ($value) { + $query->where('name', 'LIKE', "%$value%") + ->orWhere('description', 'LIKE', "%$value%"); + }); + } +} diff --git a/app/Models/Filters/FiltersAddressBlockWildcard.php b/app/Models/Filters/FiltersAddressBlockWildcard.php new file mode 100644 index 00000000000..6a0a9c42e17 --- /dev/null +++ b/app/Models/Filters/FiltersAddressBlockWildcard.php @@ -0,0 +1,24 @@ +where(function (Builder $query) use ($value) { + $query->where('name', 'LIKE', "%$value%") + ->orWhere('description', 'LIKE', "%$value%") + ->orWhere('base_ip', '=', $value) + ->orWhere('gateway', '=', $value) + ->orWhere('mac_address', '=', $value); + }); + } +} diff --git a/app/Models/Filters/FiltersAddressByNodeId.php b/app/Models/Filters/FiltersAddressByNodeId.php deleted file mode 100644 index 659d2a6bfac..00000000000 --- a/app/Models/Filters/FiltersAddressByNodeId.php +++ /dev/null @@ -1,23 +0,0 @@ -whereRaw( - " - address_pool_id IN ( - SELECT apn.address_pool_id - FROM address_pool_to_node apn - WHERE apn.node_id = ? - ) - ", - [$value], - ); - } -} \ No newline at end of file diff --git a/app/Models/Filters/FiltersAddressPoolWildcard.php b/app/Models/Filters/FiltersAddressPoolWildcard.php deleted file mode 100644 index 41373750d83..00000000000 --- a/app/Models/Filters/FiltersAddressPoolWildcard.php +++ /dev/null @@ -1,15 +0,0 @@ -where('id', $value) - ->orWhereRaw('LOWER(name) LIKE ?', ["%$value%"]); - } -} diff --git a/app/Models/Filters/FiltersAddressWildcard.php b/app/Models/Filters/FiltersAddressWildcard.php index 0dcb33ce6cb..4877365e1af 100644 --- a/app/Models/Filters/FiltersAddressWildcard.php +++ b/app/Models/Filters/FiltersAddressWildcard.php @@ -1,6 +1,6 @@ whereIn('id', $value) - ->orWhereIn('address', Arr::map($value, fn ($v) => strtolower($v))) - ->orWhereIn('mac_address', Arr::map($value, fn ($v) => strtolower($v))); - } else { - $query->where('id', $value) - ->orWhere('address', strtolower($value)) - ->orWhere('mac_address', strtolower($value)); - } + $fields = [ + 'id' => false, // false = don't convert to lowercase + 'address' => true, // true = convert to lowercase + 'mac_address' => true, + ]; + + $query->where(function (Builder $subQuery) use ($fields, $value) { + $first = true; + + foreach ($fields as $field => $convertCase) { + $method = $first ? 'where' : 'orWhere'; + $first = false; + + if (is_array($value)) { + $values = $convertCase + ? Arr::map($value, fn ($v) => strtolower($v)) + : $value; + $whereInMethod = "{$method}In"; + $subQuery->{$whereInMethod}($field, $values); + } else { + $fieldValue = $convertCase ? strtolower($value) : $value; + $subQuery->$method($field, $fieldValue); + } + } + }); } } diff --git a/app/Models/Filters/FiltersCotermWildcard.php b/app/Models/Filters/FiltersCotermWildcard.php deleted file mode 100644 index 72dfce03ac0..00000000000 --- a/app/Models/Filters/FiltersCotermWildcard.php +++ /dev/null @@ -1,15 +0,0 @@ -where('id', $value) - ->orWhereRaw('LOWER(name) LIKE ?', ["%$value%"]); - } -} \ No newline at end of file diff --git a/app/Models/Filters/FiltersLocationWildcard.php b/app/Models/Filters/FiltersLocationWildcard.php index f44f757b8f7..9edb8afe3ab 100644 --- a/app/Models/Filters/FiltersLocationWildcard.php +++ b/app/Models/Filters/FiltersLocationWildcard.php @@ -1,6 +1,6 @@ where('id', $value) - ->orWhereRaw('LOWER(short_code) LIKE ?', ["%$value%"]); + ->orWhereRaw('LOWER(short_code) LIKE ?', ["%$value%"]); } } diff --git a/app/Models/Filters/FiltersNodeWildcard.php b/app/Models/Filters/FiltersNodeWildcard.php index 5455d4c2501..a1e4e49edca 100644 --- a/app/Models/Filters/FiltersNodeWildcard.php +++ b/app/Models/Filters/FiltersNodeWildcard.php @@ -1,6 +1,6 @@ where('id', $value) - ->orWhereRaw('LOWER(fqdn) LIKE ?', ["%$value%"]) - ->orWhereRaw('LOWER(name) LIKE ?', ["%$value%"]); + if ($value === '') { + return; + } + + $query->where(function (Builder $query) use ($value) { + $query->where('fqdn', 'LIKE', "%$value%") + ->orWhere('display_name', 'LIKE', "%$value%"); + }); } } diff --git a/app/Models/Filters/FiltersServerByAddressPoolId.php b/app/Models/Filters/FiltersServerByAddressPoolId.php deleted file mode 100644 index 9bdf5975f38..00000000000 --- a/app/Models/Filters/FiltersServerByAddressPoolId.php +++ /dev/null @@ -1,24 +0,0 @@ -whereRaw( - " - id IN ( - SELECT serv.id - FROM servers serv - JOIN address_pool_to_node apn ON serv.node_id = apn.node_id - WHERE apn.address_pool_id = ? - ) - ", - [$value], - ); - } -} \ No newline at end of file diff --git a/app/Models/Filters/FiltersServerWildcard.php b/app/Models/Filters/FiltersServerWildcard.php index 91df74c56c9..067b2ebb364 100644 --- a/app/Models/Filters/FiltersServerWildcard.php +++ b/app/Models/Filters/FiltersServerWildcard.php @@ -1,18 +1,25 @@ where('id', $value) - ->orWhere('uuid', $value) - ->orWhere('uuid_short', $value) - ->orWhereRaw('LOWER(hostname) LIKE ?', ["%$value%"]) - ->orWhereRaw('LOWER(name) LIKE ?', ["%$value%"]); + if ($value === '') { + return; + } + + $query->where(function (Builder $query) use ($value) { + $query->whereRaw('LOWER(hostname) LIKE ?', ['%'.strtolower($value).'%']) + ->orWhereRaw('LOWER(name) LIKE ?', ['%'.strtolower($value).'%']) + ->orWhereRaw('LOWER(uuid) LIKE ?', ['%'.strtolower($value).'%']) + ->orWhereRaw('LOWER(uuid_short) LIKE ?', ['%'.strtolower($value).'%']); + }); } } diff --git a/app/Models/Filters/FiltersUserWildcard.php b/app/Models/Filters/FiltersUserWildcard.php index 4e263333320..217db38025d 100644 --- a/app/Models/Filters/FiltersUserWildcard.php +++ b/app/Models/Filters/FiltersUserWildcard.php @@ -1,16 +1,33 @@ where('id', $value) - ->orWhere('email', $value) - ->orWhereRaw('LOWER(name) LIKE ?', ["%$value%"]); + if ($value === '') { + return; + } + + // Grouped, so these alternatives widen only this filter rather than + // escaping alongside every other constraint on the query. + $query->where(function (Builder $query) use ($value) { + // `id` is a bigint: on Postgres, comparing it against a term that + // is not a number is an error rather than a miss, so a search for + // a name used to 500 instead of matching it. + if (ctype_digit((string) $value)) { + $query->orWhere('id', $value); + } + + $query->orWhereRaw('LOWER(email) LIKE ?', ['%'.strtolower($value).'%']) + ->orWhereRaw('LOWER(name) LIKE ?', ['%'.strtolower($value).'%']); + }); } } diff --git a/app/Models/ISO.php b/app/Models/ISO.php index 6480e1cc026..ef41e2324b8 100644 --- a/app/Models/ISO.php +++ b/app/Models/ISO.php @@ -1,47 +1,74 @@ 'boolean', - 'size' => MebibytesToAndFromBytes::class, - 'hidden' => 'boolean', - ]; + public const UPDATED_AT = null; public static array $validationRules = [ - 'node_id' => 'required|integer|exists:nodes,id', - 'is_successful' => 'sometimes|boolean', 'name' => 'required|string|min:1|max:40', + 'url' => 'nullable|url|required_without:path', + 'path' => 'nullable|string|required_without:url', + 'sha256' => 'nullable|string|size:64', 'file_name' => 'required|string|ends_with:.iso|max:191', 'size' => 'sometimes|numeric|min:0', 'hidden' => 'sometimes|boolean', - 'completed_at' => 'nullable|date', ]; - public function node(): BelongsTo + protected function casts(): array + { + return [ + 'size' => StorageSizeCast::class, + 'hidden' => 'boolean', + ]; + } + + public function getRouteKeyName(): string + { + return 'uuid'; + } + + /** Whether the panel is the one serving this file. */ + public function isHosted(): bool { - return $this->belongsTo(Node::class); + return filled($this->path); } protected static function boot(): void { parent::boot(); - static::creating(function (ISO $user) { - $user->uuid = Str::uuid()->toString(); + static::creating(function (ISO $iso) { + $iso->uuid = Str::uuid()->toString(); }); } } diff --git a/app/Models/ImageDefinition.php b/app/Models/ImageDefinition.php new file mode 100644 index 00000000000..a07d7621b34 --- /dev/null +++ b/app/Models/ImageDefinition.php @@ -0,0 +1,113 @@ + 'required|integer|exists:image_groups,id', + 'name' => 'required|string|max:40', + 'description' => 'nullable|string|max:1000', + 'is_admin_only' => 'sometimes|boolean', + 'ostype' => 'required|string|max:20', + 'hardware' => 'sometimes|array', + 'minimum_cores' => 'nullable|integer|min:1', + 'minimum_memory' => 'nullable|integer|min:1', + ]; + + protected $guarded = ['id']; + + protected function casts(): array + { + return [ + 'is_admin_only' => 'boolean', + 'hardware' => 'array', + ]; + } + + public function getRouteKeyName(): string + { + return 'uuid'; + } + + /** + * @return BelongsTo + */ + public function group(): BelongsTo + { + return $this->belongsTo(ImageGroup::class, 'image_group_id'); + } + + /** + * @return HasMany + */ + public function versions(): HasMany + { + return $this->hasMany(ImageVersion::class); + } + + /** + * The newest active version, which is what a new server gets. + * + * Ordered by the integer triple rather than the string so 1.10.0 beats + * 1.9.0. Retired versions stay queryable because servers already built from + * them still point at them; they are just never handed out again. + */ + public function latestVersion(): ?ImageVersion + { + return $this->versions() + ->where('is_active', true) + ->orderByDesc('version_major') + ->orderByDesc('version_minor') + ->orderByDesc('version_patch') + ->first(); + } + + /** + * The hardware this definition actually provisions with. + * + * The stored `hardware` is an overlay, not a specification: whatever it does + * not name comes from the `ostype`'s default. That is what lets the admin + * form ask one question and still produce a complete `qm create` call. + */ + public function effectiveHardware(): array + { + return OsProfiles::merge($this->ostype, $this->hardware ?? []); + } + + protected static function boot(): void + { + parent::boot(); + + static::creating(function (ImageDefinition $model) { + $model->uuid = Uuid::uuid4()->toString(); + }); + } +} diff --git a/app/Models/ImageGroup.php b/app/Models/ImageGroup.php new file mode 100644 index 00000000000..2411430044e --- /dev/null +++ b/app/Models/ImageGroup.php @@ -0,0 +1,64 @@ + 'required|string|max:40', + 'description' => 'nullable|string|max:1000', + 'is_admin_only' => 'sometimes|boolean', + ]; + + protected $guarded = ['id']; + + protected function casts(): array + { + return [ + 'is_admin_only' => 'boolean', + ]; + } + + public function getRouteKeyName(): string + { + return 'uuid'; + } + + /** + * @return HasMany + */ + public function definitions(): HasMany + { + return $this->hasMany(ImageDefinition::class); + } + + protected static function boot(): void + { + parent::boot(); + + static::creating(function (ImageGroup $model) { + $model->uuid = Uuid::uuid4()->toString(); + }); + } +} diff --git a/app/Models/ImageVersion.php b/app/Models/ImageVersion.php new file mode 100644 index 00000000000..c9d3a38567c --- /dev/null +++ b/app/Models/ImageVersion.php @@ -0,0 +1,149 @@ + 'required|integer|exists:image_definitions,id', + 'version' => 'required|string|max:32|regex:/^\d+\.\d+\.\d+$/', + 'disks' => 'required|array|min:1', + 'is_active' => 'sometimes|boolean', + ]; + + protected $guarded = ['id']; + + protected function casts(): array + { + return [ + 'disks' => 'array', + // Same convention as every other size column: MiB stored, bytes read. + 'size' => StorageSizeCast::class, + 'is_active' => 'boolean', + ]; + } + + public function getRouteKeyName(): string + { + return 'uuid'; + } + + /** + * @return BelongsTo + */ + public function definition(): BelongsTo + { + return $this->belongsTo(ImageDefinition::class, 'image_definition_id'); + } + + /** + * Servers built from this version. Guards deletion: a version is a server's + * only record of what it was made from. + * + * @return HasMany + */ + public function deployments(): HasMany + { + return $this->hasMany(Deployment::class); + } + + /** + * @return Collection + */ + public function diskSet(): Collection + { + return collect($this->disks ?? [])->map(fn (array $disk) => ImageDiskData::from($disk)); + } + + public function systemDisk(): ?ImageDiskData + { + return $this->diskSet()->firstWhere(fn (ImageDiskData $disk) => $disk->isSystem()); + } + + /** + * The smallest plan this version can be provisioned onto. + * + * An imported disk inherits the source's virtual size and `qm disk resize` + * only grows, so the system disk's provisioned size is a hard floor rather + * than a suggestion. + */ + public function minimumDiskSize(): int + { + return $this->systemDisk()?->virtualSize ?? 0; + } + + /** + * Keep the derived columns in step with what an operator actually set. + * + * Hung off `creating` and `updating` rather than `saving`, which is not a + * style choice: {@see Model::boot} registers a `saving` + * listener that returns `true`, and model events halt on the first non-null + * return -- so a `saving` listener added afterwards never runs at all. It + * fails silently, which is how the version triple below sat at 0/0/0 and + * made `latestVersion()` return an arbitrary row. + */ + protected static function boot(): void + { + parent::boot(); + + static::creating(function (ImageVersion $model) { + $model->uuid = Uuid::uuid4()->toString(); + self::syncDerivedColumns($model); + }); + + static::updating(function (ImageVersion $model) { + self::syncDerivedColumns($model); + }); + } + + private static function syncDerivedColumns(ImageVersion $model): void + { + // Ordered by the integer triple rather than the string, so 1.10.0 beats + // 1.9.0. Derived here so nobody has to remember four fields. + if ($model->isDirty('version')) { + [$major, $minor, $patch] = array_pad( + array_map('intval', explode('.', (string) $model->version)), + 3, + 0, + ); + + $model->version_major = $major; + $model->version_minor = $minor; + $model->version_patch = $patch; + } + + if ($model->isDirty('disks')) { + // The disks JSON is in bytes -- a cast cannot reach inside a JSON + // column -- and the cast on this attribute scales the sum down to + // the mebibytes the column stores. + $model->size = collect($model->disks ?? [])->sum(fn (array $disk) => (int) ($disk['size'] ?? 0)); + } + } +} diff --git a/app/Models/Location.php b/app/Models/Location.php index 2925bb0a1a6..b8884a8c005 100644 --- a/app/Models/Location.php +++ b/app/Models/Location.php @@ -1,19 +1,28 @@ */ protected $guarded = ['id', 'created_at', 'updated_at']; diff --git a/app/Models/Model.php b/app/Models/Model.php index 0b826d06ed7..4d56efa0bc4 100644 --- a/app/Models/Model.php +++ b/app/Models/Model.php @@ -1,9 +1,9 @@ make(Factory::class); + // Returns nothing on purpose. Eloquent dispatches model events with + // `until()`, so any non-null return halts the rest of the chain -- and + // this listener is registered first, by every model in the app. A bare + // `return true` here silently disabled every `saving` listener a + // subclass added afterwards, which is not a failure anything reports: + // the code simply never runs. Validation still stops a bad save by + // throwing, which is the only signal that was ever load-bearing. static::saving(function (Model $model) { try { $model->validate(); } catch (ValidationException $exception) { throw new DataValidationException($exception->validator, $model); } - - return true; }); } @@ -89,7 +94,13 @@ public function getValidator(): Validator { $rules = $this->exists ? static::getRulesForUpdate($this) : static::getRules(); - return static::$validatorFactory->make([], $rules); + $validator = static::$validatorFactory->make([], $rules); + + if (! $validator instanceof Validator) { + throw new \LogicException('Expected Laravel validation factory to return a concrete validator.'); + } + + return $validator; } /** @@ -119,10 +130,10 @@ public static function getRulesForField(string $field): array * rather than just creating it. */ public static function getRulesForUpdate( - IlluminateModel|int|string $model, string $column = 'id', - ): array - { - if ($model instanceof Model) { + IlluminateModel|int|string $model, + string $column = 'id', + ): array { + if ($model instanceof self) { [$id, $column] = [$model->getKey(), $model->getKeyName()]; } @@ -133,7 +144,7 @@ public static function getRulesForUpdate( // working model, so we don't run into errors due to the way that field validation // works. foreach ($data as &$datum) { - if (!is_string($datum) || !Str::startsWith($datum, 'unique')) { + if (! is_string($datum) || ! Str::startsWith($datum, 'unique')) { continue; } @@ -158,16 +169,16 @@ public function validate(): void $validator = $this->getValidator(); $validator->setData( - // Trying to do self::toArray() here will leave out keys based on the whitelist/blacklist - // for that model. Doing this will return all the attributes in a format that can - // properly be validated. + // Trying to do self::toArray() here will leave out keys based on the whitelist/blacklist + // for that model. Doing this will return all the attributes in a format that can + // properly be validated. $this->addCastAttributesToArray( $this->getAttributes(), $this->getMutatedAttributes(), ), ); - if (!$validator->passes()) { + if (! $validator->passes()) { throw new ValidationException($validator); } } @@ -177,7 +188,7 @@ public function validate(): void */ protected function asDateTime(mixed $value): Carbon|CarbonImmutable { - if (!$this->immutableDates) { + if (! $this->immutableDates) { return parent::asDateTime($value); } diff --git a/app/Models/NetworkInterface.php b/app/Models/NetworkInterface.php new file mode 100644 index 00000000000..abb30277ede --- /dev/null +++ b/app/Models/NetworkInterface.php @@ -0,0 +1,163 @@ + $addressBlockGroups + * @property Collection $servers + */ +class NetworkInterface extends Model +{ + use HasFactory; + + /** + * Resolved VLAN usage (tag => server count) for this bridge. + * + * A declared property rather than an attribute, so Eloquent's `__set` never + * sees it and it can't be mistaken for a column on save. It only exists so + * a list can fill it from one batched `vlanUsageFor()` call instead of + * letting each interface query for itself; leave it null and `vlanUsage()` + * still answers correctly on its own. + */ + public ?Collection $resolvedVlanUsage = null; + + public $timestamps = false; + + protected $guarded = [ + 'id', + ]; + + public static array $validationRules = [ + 'node_id' => 'required|integer|exists:nodes,id', + 'name' => 'required|string|min:1|max:40', + 'description' => 'nullable|string|max:191', + 'is_vlan_aware' => 'sometimes|boolean', + 'vlan_tag' => 'nullable|integer|min:1|max:4094', + ]; + + protected function casts(): array + { + return [ + 'is_vlan_aware' => 'boolean', + 'vlan_tag' => 'integer', + ]; + } + + public function node(): BelongsTo + { + return $this->belongsTo(Node::class); + } + + /** + * Servers attached to this interface. The FK is `nullOnDelete`, so a + * deleted interface leaves its servers behind unattached rather than + * cascading — this counts only what is currently on the bridge. + * + * @return HasMany + */ + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } + + /** + * VLANs declared on this bridge. Declaration is independent of use — a + * freshly configured trunk can have VLANs with no servers on them yet. + * + * @return HasMany + */ + public function vlans(): HasMany + { + return $this->hasMany(Vlan::class); + } + + /** + * How many servers resolve to each tag on this bridge, keyed by tag. + * + * A server on an aware bridge with a null `vlan_tag` inherits the bridge + * default, so the grouping has to be on the resolved value — grouping on + * `servers.vlan_tag` alone would file those under "untagged" while Proxmox + * has them on the bridge's tag. A non-aware bridge forces a null tag for + * every server on it, so there is nothing to group. + * + * @return Collection + */ + public function vlanUsage(): Collection + { + return $this->resolvedVlanUsage + ??= static::vlanUsageFor([$this])->get($this->id) ?? collect(); + } + + /** + * The same counts for many bridges in one query, since a node's whole + * interface list needs them at once. + * + * The `COALESCE` is what resolves inheritance, and filtering on it (rather + * than on `servers.vlan_tag`) is also what keeps a pure trunk's untagged + * servers out: with no bridge default to fall back to, they coalesce to + * null and drop away. + * + * @param iterable $interfaces + * @return Collection> interface id => tag => count + */ + public static function vlanUsageFor(iterable $interfaces): Collection + { + $ids = collect($interfaces) + ->filter(fn (self $interface) => $interface->is_vlan_aware) + ->pluck('id'); + + if ($ids->isEmpty()) { + return collect(); + } + + return Server::query() + ->join( + 'network_interfaces', + 'servers.network_interface_id', + '=', + 'network_interfaces.id', + ) + ->whereIn('network_interfaces.id', $ids) + ->selectRaw('network_interfaces.id as interface_id') + ->selectRaw('COALESCE(servers.vlan_tag, network_interfaces.vlan_tag) as resolved_tag') + ->selectRaw('COUNT(*) as total') + ->whereRaw('COALESCE(servers.vlan_tag, network_interfaces.vlan_tag) IS NOT NULL') + ->groupBy('network_interfaces.id', 'resolved_tag') + ->get() + ->groupBy('interface_id') + ->map(fn (Collection $rows) => $rows->mapWithKeys( + fn ($row) => [(int) $row->resolved_tag => (int) $row->total], + )); + } + + /** + * @return BelongsToMany + */ + public function addressBlockGroups(): BelongsToMany + { + return $this->belongsToMany( + AddressBlockGroup::class, + 'address_block_group_to_network_interface', + 'network_interface_id', + 'address_block_group_id' + ); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/Node.php b/app/Models/Node.php index 0ae9a9306a3..0e5c963235b 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -1,34 +1,79 @@ |null $agent_capabilities + * @property array|null $agent_reported_facts + * @property ?OveragePenaltyData $overage_penalty + * @property ?Relay $relay + * @property-read ?StorageToNode $pivot Present when reached through Storage::nodes(). + */ class Node extends Model { - use HasFactory; + use AnchorInstallation, HasFactory, HasRelationships; /** * The attributes excluded from the model's JSON form. */ protected $hidden = [ 'token_id', - 'secret', - ]; - - /** - * Cast values to correct type. - */ - protected $casts = [ - 'verify_tls' => 'boolean', - 'memory' => MebibytesToAndFromBytes::class, - 'disk' => MebibytesToAndFromBytes::class, - 'secret' => 'encrypted', + 'token_secret', + 'agent_secret', + 'agent_enrollment_token_hash', ]; /** @@ -38,109 +83,297 @@ class Node extends Model public static array $validationRules = [ 'location_id' => 'required|integer|exists:locations,id', + 'display_name' => 'required|string|max:191', 'name' => 'required|string|max:191', - 'cluster' => 'required|string|max:191', 'verify_tls' => 'sometimes|boolean', 'fqdn' => 'required|string|max:191', 'token_id' => 'required|string|max:191', - 'secret' => 'required|string|max:191', + 'token_secret' => 'required|string|max:191', 'port' => 'required|integer|min:1|max:65535', + 'socket_count' => 'required|integer|min:1', + 'core_count' => 'required|integer|min:1', + 'cpu_count' => 'required|integer|min:1', 'memory' => 'required|integer', 'memory_overallocate' => 'required|integer', - 'disk' => 'required|integer', - 'disk_overallocate' => 'required|integer', - 'vm_storage' => ['required', 'string', 'max:191', 'regex:/^\S*$/u'], - 'backup_storage' => ['required', 'string', 'max:191', 'regex:/^\S*$/u'], - 'iso_storage' => ['required', 'string', 'max:191', 'regex:/^\S*$/u'], - 'network' => ['required', 'string', 'max:191', 'regex:/^\S*$/u'], - 'coterm_id' => 'sometimes|nullable|integer|exists:coterms,id', + // 'network' => ['required', 'string', 'max:191', 'regex:/^\S*$/u'], + // The agent installed on this host. Every column is nullable and stays + // that way: a node upgraded from v4 has no agent at all, and inventing + // one to satisfy a constraint would record a machine that does not exist. + 'agent_uuid' => 'sometimes|nullable|uuid', + 'agent_public_url' => 'sometimes|nullable|url:http,https|max:2048', + 'agent_panel_url_override' => 'sometimes|nullable|url:http,https|max:2048', + 'relay_id' => 'sometimes|nullable|integer|exists:relays,id', + // Per-node override of the quota-overage penalty; null = inherit the global + // BandwidthSettings default. See docs/bandwidth-rate-limiting-plan.md §5. + 'overage_penalty' => 'sometimes|nullable|array', + 'overage_penalty.action' => 'required_with:overage_penalty|string|in:throttle,disconnect', + 'overage_penalty.rate' => 'nullable|integer|min:1', ]; /** - * Get the connection address to use when making calls to this node's assigned Coterm endpoint. + * Get the attributes that should be cast. + * + * @return array */ - public function getCotermConnectionAddress(): string + protected function casts(): array { - return sprintf( - '%s://%s:%s', $this->coterm_tls_enabled ? 'https' : 'http', $this->coterm_fqdn, - $this->coterm_port, - ); + return [ + 'verify_tls' => 'boolean', + 'agent_secret' => 'encrypted', + 'agent_enrollment_expires_at' => 'datetime', + 'agent_enrolled_at' => 'datetime', + 'agent_last_seen_at' => 'datetime', + 'agent_protocol_min' => 'integer', + 'agent_protocol_max' => 'integer', + 'agent_capabilities' => 'array', + 'agent_reported_facts' => 'array', + 'memory' => StorageSizeCast::class, + 'token_secret' => 'encrypted', + 'overage_penalty' => OveragePenaltyCast::class, + 'status' => NodeStatus::class, + 'status_code' => ConnectionErrorCode::class, + 'last_seen_at' => 'datetime', + 'status_checked_at' => 'datetime', + 'consecutive_failures' => 'integer', + ]; + } + + /** + * How long a recorded status stays trustworthy. + * + * `nodes:poll` runs every minute, so this is generous enough to survive a + * skipped pass or a briefly backed-up queue. + */ + public const STATUS_TTL_MINUTES = 5; + + /** + * The stored status, degraded to `unknown` once the last check is too old + * to stand behind. + * + * Without this, an install whose scheduler or queue worker has stopped + * would keep reporting whatever was true when it last ran — a node could + * read `online` for weeks after it burned down. A remembered answer is not + * an observation, and the difference matters most exactly when the + * monitoring itself is broken. + */ + public function currentStatus(): NodeStatus + { + if ( + $this->status_checked_at === null + || $this->status_checked_at->lt(now()->subMinutes(self::STATUS_TTL_MINUTES)) + ) { + return NodeStatus::UNKNOWN; + } + + return $this->status; } /** * Gets the servers associated with a node. */ + /** + * @return HasMany + */ public function servers(): HasMany { return $this->hasMany(Server::class); } /** - * Gets the address pools allocated to a node. + * Gets all the addresses allocated to a node, resolved through the node's + * network interfaces → address block groups → address blocks. */ - public function addressPools(): BelongsToMany + public function addresses(): HasManyDeep { - return $this->belongsToMany( - AddressPool::class, - 'address_pool_to_node', - 'node_id', - 'address_pool_id', + return $this->hasManyDeep( + Address::class, + [NetworkInterface::class, 'address_block_group_to_network_interface', AddressBlockGroup::class, AddressBlock::class], + [ + 'node_id', // network_interfaces.node_id → nodes.id + 'network_interface_id', // pivot.network_interface_id → network_interfaces.id + 'id', // address_block_groups.id ← pivot.address_block_group_id + 'address_block_group_id', // address_blocks.address_block_group_id → address_block_groups.id + 'address_block_id', // addresses.address_block_id → address_blocks.id + ], + [ + 'id', // nodes.id + 'id', // network_interfaces.id + 'address_block_group_id', // pivot.address_block_group_id + 'id', // address_block_groups.id + 'id', // address_blocks.id + ], ); } /** - * Gets all the addresses associated with a node from the address pool(s) allocated to a node. + * Gets the location associated with a node. + */ + /** + * @return BelongsTo */ - public function addresses(): HasManyThrough + public function location(): BelongsTo { - return $this->hasManyThrough( - Address::class, - AddressPoolToNode::class, - 'node_id', - 'address_pool_id', - 'id', - 'address_pool_id', - ); + return $this->belongsTo(Location::class); } /** - * Gets the template groups associated with a node. This is not the same as TEMPLATES. + * @return HasMany */ - public function templateGroups(): HasMany + public function networkInterfaces(): HasMany { - return $this->hasMany(TemplateGroup::class); + return $this->hasMany(NetworkInterface::class); } /** - * Gets the ISOs downloaded on a node. + * The storage scope this node resolves into: its PVE cluster, or its own + * singleton scope when standalone. Null only before the first successful + * poll or registration-time resolution. */ - public function isos(): HasMany + /** + * @return BelongsTo + */ + public function cluster(): BelongsTo { - return $this->hasMany(ISO::class); + return $this->belongsTo(Cluster::class); } /** - * Gets the location associated with a node. + * Gets the Anchor agent connected with this node. */ - public function location(): BelongsTo + /** + * @return BelongsTo + */ + /** @return BelongsTo */ + public function relay(): BelongsTo { - return $this->belongsTo(Location::class); + return $this->belongsTo(Relay::class, 'relay_id'); + } + + /** @return BelongsTo */ + public function agentEnrollmentKey(): BelongsTo + { + return $this->belongsTo(AnchorEnrollmentKey::class, 'agent_enrollment_key_id'); + } + + public function anchorName(): string + { + return $this->display_name; + } + + public function anchorUuid(): ?string + { + return $this->agent_uuid; + } + + public function anchorSecret(): ?string + { + return $this->agent_secret; + } + + public function anchorEnrolledAt(): ?Carbon + { + return $this->agent_enrolled_at; + } + + public function anchorLastSeenAt(): ?Carbon + { + return $this->agent_last_seen_at; + } + + public function anchorProtocolMin(): ?int + { + return $this->agent_protocol_min; + } + + public function anchorProtocolMax(): ?int + { + return $this->agent_protocol_max; + } + + public function anchorPublicUrl(): ?string + { + return $this->agent_public_url; + } + + public function anchorPanelUrlOverride(): ?string + { + return $this->agent_panel_url_override; + } + + /** A node's installation is always the agent; a relay is never a node. */ + public function anchorMode(): AnchorMode + { + return AnchorMode::AGENT; + } + + /** @param array $payload */ + public function recordAnchorHeartbeat(array $payload): void + { + // Writes the agent's liveness, never the node's. `last_seen_at` and + // `status` describe whether Proxmox answers, which stays a separate + // question -- a running daemon on a host whose API is down must not + // read as a healthy node. + $this->update([ + 'agent_last_seen_at' => now(), + 'agent_version' => $payload['version'], + 'agent_protocol_min' => $payload['protocol_min'], + 'agent_protocol_max' => $payload['protocol_max'], + 'agent_capabilities' => $payload['capabilities'], + ]); + } + + /** + * @return BelongsToMany + */ + public function storages(): BelongsToMany + { + return $this->belongsToMany( + Storage::class, + 'storage_to_node', + 'node_id', + 'storage_id', + ) + ->using(StorageToNode::class) + ->withPivot('backup_order', 'discovered_total', 'discovered_used', 'discovered_at'); + } + + /** + * A storage on this node capable of holding ISOs. Used as the default when + * uploading a new ISO (the user may override the selection). + */ + public function isoStorage(): ?Storage + { + return $this->storages()->stores(StorageContentType::ISO)->first(); + } + + /** + * A storage on this node that accepts importable disk images. + * + * PVE keeps `import` off by default, so a node having plenty of space is no + * guarantee it has anywhere an image can land. Callers treat null as "this + * node cannot take images yet" rather than as an error. + */ + public function importStorage(): ?Storage + { + return $this->storages()->stores(StorageContentType::IMPORT)->first(); } /** - * Gets the instance of Coterm that's connected with this node. + * A storage on this node capable of holding backups. */ - public function coterm(): BelongsTo + public function backupStorage(): ?Storage { - return $this->belongsTo(Coterm::class); + return $this->storages()->stores(StorageContentType::BACKUPS)->first(); } /** - * Gets the total disk used from adding up all the associated servers' disk sizes. + * Whether a backup could be stored at all. Cheaper than backupStorage() when + * the caller only needs to know that one exists -- the client uses it to + * disable the create action up front instead of failing the request. */ - public function getDiskAllocatedAttribute(): int + public function hasBackupStorage(): bool { - return $this->servers->sum('disk'); + return $this->storages()->stores(StorageContentType::BACKUPS)->exists(); } /** diff --git a/app/Models/OAuthConnection.php b/app/Models/OAuthConnection.php new file mode 100644 index 00000000000..f6f63722a60 --- /dev/null +++ b/app/Models/OAuthConnection.php @@ -0,0 +1,56 @@ + 'required|integer|exists:users,id', + 'provider' => 'required|string|max:191', + 'provider_id' => 'required|string|max:191', + 'name' => 'nullable|string|max:191', + 'email' => 'nullable|string|max:191', + 'last_used_at' => 'nullable|date', + ]; + + protected function casts(): array + { + return [ + 'last_used_at' => 'datetime', + ]; + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + /** OAuth connections have no uuid; bind by primary key (the base Model defaults to uuid). */ + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/Passkey.php b/app/Models/Passkey.php new file mode 100644 index 00000000000..d9f5df57f9b --- /dev/null +++ b/app/Models/Passkey.php @@ -0,0 +1,57 @@ + 'required|string|max:'.self::NAME_MAX_LENGTH, + ]; + + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } +} diff --git a/app/Models/PersonalAccessToken.php b/app/Models/PersonalAccessToken.php index 3dee51a0d4b..f86b8b39a62 100644 --- a/app/Models/PersonalAccessToken.php +++ b/app/Models/PersonalAccessToken.php @@ -1,10 +1,17 @@ $allowed_networks + * @property ?User $createdBy + */ class PersonalAccessToken extends SanctumPersonalAccessToken { /** @@ -15,11 +22,28 @@ class PersonalAccessToken extends SanctumPersonalAccessToken 'name', 'token', 'abilities', + 'allowed_networks', + 'created_by', ]; - protected $casts = [ - 'type' => ApiKeyType::class, - 'abilities' => 'json', - 'last_used_at' => 'datetime', - ]; + /** + * The admin who minted this token. Kept for audit; nulled (not cascaded) if that user is + * deleted, so an application token outlives its creator. + * + * @return BelongsTo + */ + public function createdBy(): BelongsTo + { + return $this->belongsTo(User::class, 'created_by'); + } + + protected function casts(): array + { + return [ + 'type' => ApiKeyType::class, + 'abilities' => 'json', + 'allowed_networks' => 'array', + 'last_used_at' => 'datetime', + ]; + } } diff --git a/app/Models/Relay.php b/app/Models/Relay.php new file mode 100644 index 00000000000..f3ef40494c9 --- /dev/null +++ b/app/Models/Relay.php @@ -0,0 +1,155 @@ +|null $capabilities + * @property array|null $reported_facts + */ +class Relay extends Model +{ + use AnchorInstallation, HasFactory; + + protected $guarded = ['id', 'created_at', 'updated_at']; + + protected $hidden = ['secret', 'enrollment_token_hash']; + + public static array $validationRules = [ + 'uuid' => 'required|uuid', + 'name' => 'required|string|max:191', + 'public_url' => 'nullable|url:http,https|max:2048', + 'panel_url_override' => 'nullable|url:http,https|max:2048', + 'secret' => 'required|string|min:32', + 'enrollment_key_id' => 'nullable|integer|exists:anchor_enrollment_keys,id', + 'enrollment_token_hash' => 'nullable|string|size:64', + 'enrollment_expires_at' => 'nullable|date', + 'enrolled_at' => 'nullable|date', + 'last_seen_at' => 'nullable|date', + 'version' => 'nullable|string|max:191', + 'protocol_min' => 'nullable|integer|min:1', + 'protocol_max' => 'nullable|integer|min:1', + 'capabilities' => 'nullable|array', + 'reported_facts' => 'nullable|array', + ]; + + protected function casts(): array + { + return [ + 'secret' => 'encrypted', + 'enrollment_expires_at' => 'datetime', + 'enrolled_at' => 'datetime', + 'last_seen_at' => 'datetime', + 'protocol_min' => 'integer', + 'protocol_max' => 'integer', + 'capabilities' => 'array', + 'reported_facts' => 'array', + ]; + } + + /** @return HasMany */ + public function nodes(): HasMany + { + return $this->hasMany(Node::class, 'relay_id'); + } + + /** @return BelongsTo */ + public function enrollmentKey(): BelongsTo + { + return $this->belongsTo(AnchorEnrollmentKey::class, 'enrollment_key_id'); + } + + public function anchorName(): string + { + return $this->name; + } + + public function anchorUuid(): ?string + { + return $this->uuid; + } + + public function anchorSecret(): ?string + { + return $this->secret; + } + + public function anchorEnrolledAt(): ?Carbon + { + return $this->enrolled_at; + } + + public function anchorLastSeenAt(): ?Carbon + { + return $this->last_seen_at; + } + + public function anchorProtocolMin(): ?int + { + return $this->protocol_min; + } + + public function anchorProtocolMax(): ?int + { + return $this->protocol_max; + } + + public function anchorPublicUrl(): ?string + { + return $this->public_url; + } + + public function anchorPanelUrlOverride(): ?string + { + return $this->panel_url_override; + } + + public function anchorMode(): AnchorMode + { + return AnchorMode::RELAY; + } + + /** @param array $payload */ + public function recordAnchorHeartbeat(array $payload): void + { + $this->update([ + 'last_seen_at' => now(), + 'version' => $payload['version'], + 'protocol_min' => $payload['protocol_min'], + 'protocol_max' => $payload['protocol_max'], + 'capabilities' => $payload['capabilities'], + ]); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/SSHKey.php b/app/Models/SSHKey.php index 899aafad597..39bde010fcb 100644 --- a/app/Models/SSHKey.php +++ b/app/Models/SSHKey.php @@ -1,6 +1,6 @@ belongsTo(User::class); } + + /** SSH keys have no uuid; bind by primary key (the base Model defaults to uuid). */ + public function getRouteKeyName(): string + { + return 'id'; + } } diff --git a/app/Models/Server.php b/app/Models/Server.php index c8b4f81c813..f13ccfb3181 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -1,129 +1,326 @@ $disks + * @property ?ServerDisk $primaryDisk + * @property ?Address $primaryIPv4Address + * @property ?Address $primaryIPv6Address + */ class Server extends Model { use HasFactory; - protected $casts = [ - 'memory' => MebibytesToAndFromBytes::class, - 'disk' => MebibytesToAndFromBytes::class, - 'bandwidth_usage' => MebibytesToAndFromBytes::class, - 'bandwidth_limit' => MebibytesToAndFromBytes::class, - ]; + public const UPDATED_AT = null; protected $guarded = [ 'id', - 'updated_at', + 'uuid', + 'uuid_short', 'created_at', ]; public static array $validationRules = [ 'name' => 'required|string|min:1|max:40', 'node_id' => 'required|integer|exists:nodes,id', + 'storage_id' => 'required|integer|exists:storages,id', + 'network_interface_id' => 'nullable|integer|exists:network_interfaces,id', 'user_id' => 'required|integer|exists:users,id', 'vmid' => 'required|numeric|min:100|max:999999999', 'hostname' => 'required|string|min:1|max:191', - 'status' => ['sometimes', 'nullable', 'string', 'in:installing,install_failed,suspended,restoring_backup,restoring_snapshot,deleting,deletion_failed'], + 'lifecycle' => ['sometimes', 'string', 'in:ready,deferred_os_selection,installing,install_failed,restoring_backup,deleting,deletion_failed'], + 'suspended_at' => ['sometimes', 'nullable', 'date'], 'cpu' => 'required|numeric|min:1', 'memory' => 'required|numeric|min:16777216', 'disk' => 'required|numeric|min:1', 'bandwidth_usage' => 'sometimes|numeric|min:0', - 'snapshot_limit' => 'present|nullable|integer|min:0', - 'backup_limit' => 'present|nullable|integer|min:0', - 'bandwidth_limit' => 'present|nullable|integer|min:0', + 'backup_count_limit' => 'required|integer|min:-1', + 'backup_size_limit' => 'required|integer|min:-1', + 'bandwidth_limit' => 'present|integer|min:-1', + // Persistent NIC speed cap in bytes/s (null = unlimited); the request layer + // converts the operator's MB/s input. See docs/bandwidth-rate-limiting-plan.md. + 'speed_limit' => 'sometimes|nullable|integer|min:0', + // Per-server override of the quota-overage penalty; null = inherit. Nested + // shape is validated where it's exposed (UpdateBuildRequest). + 'overage_penalty' => 'sometimes|nullable|array', + 'overage_penalty.action' => 'required_with:overage_penalty|string|in:throttle,disconnect', + 'overage_penalty.rate' => 'nullable|integer|min:1', + 'bandwidth_reset_day' => 'sometimes|nullable|integer|min:1|max:31', + 'vlan_tag' => 'nullable|integer|min:1|max:4094', 'hydrated_at' => 'nullable|date', ]; + protected function casts(): array + { + return [ + 'lifecycle' => ServerLifecycle::class, + 'suspended_at' => 'immutable_datetime', + 'flagged_at' => 'immutable_datetime', + 'memory' => StorageSizeCast::class, + 'disk' => StorageSizeCast::class, + 'bandwidth_usage' => StorageSizeCast::class, + 'bandwidth_limit' => StorageSizeCast::class, + 'backup_size_limit' => StorageSizeCast::class, + 'speed_limit' => 'integer', + 'overage_penalty' => OveragePenaltyCast::class, + 'bandwidth_reset_day' => 'integer', + 'vlan_tag' => 'integer', + ]; + } + + /** + * @return BelongsTo + */ public function node(): BelongsTo { return $this->belongsTo(Node::class); } + /** + * @return BelongsTo + */ + public function networkInterface(): BelongsTo + { + return $this->belongsTo(NetworkInterface::class); + } + + /** + * The server's primary/boot storage. Expand-first: this column is still the + * source of truth for the primary disk's storage (the template clone reads + * it). It is mirrored by the `is_primary` row in {@see disks()}. + * + * @return BelongsTo + */ + public function storage(): BelongsTo + { + return $this->belongsTo(Storage::class); + } + + /** + * All of the server's disks (one primary + zero or more secondary). + * + * @return HasMany + */ + public function disks(): HasMany + { + return $this->hasMany(ServerDisk::class); + } + + /** + * The primary/boot disk row. + * + * @return HasOne + */ + public function primaryDisk(): HasOne + { + return $this->hasOne(ServerDisk::class)->where('is_primary', true); + } + public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } - public function addresses(): HasMany + /** + * Scope the query to servers the given user owns. + * + * This is the single source of truth for client-facing server visibility. + * Ownership is deliberate for everyone, including root admins — the client + * area shows a user their own servers, not every server on the panel (use + * the admin area for that). When subuser support is added, extend the + * ownership check here (e.g. an orWhereHas on a subusers relation) and + * every listing inherits it. + * + * @param Builder $query + */ + public function scopeOwnedBy(Builder $query, User $user): void { - return $this->hasMany(Address::class); + $query->where('user_id', $user->id); } - public function template(): HasOne + /** + * @return HasMany + */ + public function addresses(): HasMany { - return $this->hasOne(Template::class); + return $this->hasMany(Address::class); } + /** + * @return HasMany + */ public function backups(): HasMany { return $this->hasMany(Backup::class); } /** - * The ISOs this server is able to mount. - * - * ISO images live on a node (Node::isos()), not on an individual server, so - * this is an availability relationship rather than an ownership one: it - * matches on node_id at both ends instead of on a server_id column. - * - * Naming it isos() is deliberate. Scoped route-model binding resolves - * {iso} nested under {server} by calling Str::plural('iso') on the parent, - * so this relationship is what makes the /settings/hardware/isos/{iso} - * routes reject an ISO belonging to another node. Renaming or removing it - * turns those routes into a global lookup by uuid. + * @return HasMany + */ + public function deployments(): HasMany + { + return $this->hasMany(Deployment::class); + } + + public function primaryIPv4Address(): HasOne + { + return $this->hasOne(Address::class, 'id', 'primary_ipv4_address_id'); + } + + public function primaryIPv6Address(): HasOne + { + return $this->hasOne(Address::class, 'id', 'primary_ipv6_address_id'); + } + + /** + * Every audit entry where this server is the thing that was acted on. Includes actions taken + * by staff, not just by the owner; see App\Enums\Audit\AuditEvent::visibility() for which of + * those a non-admin is allowed to see. + */ + public function auditLogs(): MorphMany + { + return $this->morphMany(AuditLog::class, 'subject'); + } + + /** + * Whether the server has blown its monthly bandwidth quota. A negative + * `bandwidth_limit` (the -1 sentinel) means unlimited and is never "over". */ - public function isos(): HasMany + public function isOverBandwidthQuota(): bool { - return $this->hasMany(ISO::class, 'node_id', 'node_id'); + return $this->bandwidth_limit >= 0 + && $this->bandwidth_usage >= $this->bandwidth_limit; } /** - * Returns all the activity log entries where the server is the subject. + * The day-of-month (1-31) the monthly quota resets on, falling back to the + * server's creation day when no explicit anchor is stored. */ - public function activity(): MorphToMany + public function bandwidthResetDay(): int { - return $this->morphToMany(ActivityLog::class, 'subject', 'activity_log_subjects'); + return $this->bandwidth_reset_day ?? $this->created_at->day; } public function isInstalled(): bool { - return $this->status !== Status::INSTALLING->value; + return $this->lifecycle->isInstalled(); } public function isInstalling(): bool { - return $this->status === Status::INSTALLING->value; + return $this->lifecycle->isInstalling(); } + /** + * Whether the server is administratively suspended. + * + * Read off its own column rather than the lifecycle: suspension coexists with whatever + * stage the server is in, so a suspended server can also be `installing` or `ready`. + * Callers that want "usable right now" need both this and {@see isReady()}. + */ public function isSuspended(): bool { - return $this->status === Status::SUSPENDED->value; + return $this->suspended_at !== null; + } + + /** + * Whether the server has finished provisioning with nothing in flight. + * + * Says nothing about suspension -- see {@see isSuspended()}. + */ + public function isReady(): bool + { + return $this->lifecycle->isReady(); + } + + /** + * Total bytes consumed by this server's non-failed backups. + * + * `backups.size` is persisted in MiB (StorageSizeCast) but read back as + * bytes, and a SQL aggregate bypasses the cast entirely — so the sum has to + * be scaled the same way the cast's read direction does. + */ + public function nonFailedBackupSize(): int + { + return ByteUnit::Mebibytes->toBytes( + (int) $this->backups()->nonFailed()->sum('size'), + ); } /** - * Checks if the server is currently in a user-accessible state. If not, an - * exception is raised. This should be called whenever something needs to make - * sure the server is not in a weird state that should block user access. + * Whether no server in the node's scope already holds this VMID. * - * @throws ServerStatusConflictException + * The scope is the cluster, not the node: PVE enforces vmid uniqueness + * cluster-wide, and the placement reconciler looks servers up by + * (cluster, vmid) after an HA move -- two rows sharing a vmid inside one + * cluster would make that lookup ambiguous. A standalone or not-yet- + * resolved node falls back to checking itself alone. */ - public function validateCurrentState(): void + public static function isUniqueVmId(Node $node, int $vmid): bool { - if ( - !is_null($this->status) - ) { - throw new ServerStatusConflictException($this); + $query = static::query()->where('vmid', $vmid); + + if ($node->cluster_id !== null && ! $node->cluster->isStandalone()) { + $query->whereHas('node', fn (Builder $q) => $q->where('cluster_id', $node->cluster_id)); + } else { + $query->where('node_id', $node->id); } + + return ! $query->exists(); + } + + /** + * Whether a given UUID and UUID-Short string are unique to a server. + */ + public static function isUniqueUuidCombo(string $uuid, string $short): bool + { + return ! static::query() + ->where('uuid', $uuid) + ->orWhere('uuid_short', $short) + ->exists(); } } diff --git a/app/Models/ServerDisk.php b/app/Models/ServerDisk.php new file mode 100644 index 00000000000..e4d19829877 --- /dev/null +++ b/app/Models/ServerDisk.php @@ -0,0 +1,67 @@ + StorageSizeCast::class, + 'is_primary' => 'boolean', + ]; + } + + /** + * @return BelongsTo + */ + public function server(): BelongsTo + { + return $this->belongsTo(Server::class); + } + + /** + * @return BelongsTo + */ + public function storage(): BelongsTo + { + return $this->belongsTo(Storage::class); + } +} diff --git a/app/Models/ServerPreset.php b/app/Models/ServerPreset.php new file mode 100644 index 00000000000..74e97303a15 --- /dev/null +++ b/app/Models/ServerPreset.php @@ -0,0 +1,55 @@ + 'required|string|between:1,191|unique:server_presets,name', + 'description' => 'nullable|string|between:1,191', + 'settings' => 'required|array', + ]; + + protected function casts(): array + { + return [ + 'settings' => 'array', + ]; + } + + public function getRouteKeyName(): string + { + return 'uuid'; + } + + protected static function boot(): void + { + parent::boot(); + + static::creating(function (self $model) { + $model->uuid = Uuid::uuid4()->toString(); + }); + } +} diff --git a/app/Models/SessionRecord.php b/app/Models/SessionRecord.php new file mode 100644 index 00000000000..9c39a5d11d4 --- /dev/null +++ b/app/Models/SessionRecord.php @@ -0,0 +1,72 @@ + 'datetime', + ]; + } + + /** + * @return BelongsTo + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + /** SessionRecords have no uuid; bind by primary key (the base Model defaults to uuid). */ + public function getRouteKeyName(): string + { + return 'id'; + } + + /** + * Garbage-collect rows for sessions that can no longer exist: once a row hasn't been refreshed + * for the full session lifetime, its Redis session has expired too, so the metadata is dead + * weight. Read-time reconciliation in the controller handles listed sessions; this bounds table + * growth for sessions that are never listed. + * + * @return Builder + */ + public function prunable(): Builder + { + return static::query()->where( + 'last_active_at', + '<', + now()->subMinutes((int) config('session.lifetime')), + ); + } +} diff --git a/app/Models/Storage.php b/app/Models/Storage.php new file mode 100644 index 00000000000..aaf843a3987 --- /dev/null +++ b/app/Models/Storage.php @@ -0,0 +1,334 @@ + 'nullable|string|max:40', + 'description' => 'nullable|string|max:191', + 'name' => 'required|string|max:191', + 'size' => 'required|numeric|min:1', + 'reserved_bytes' => 'nullable|numeric|min:0', + // No `stores_*` rules: the content flags are never submitted. They are + // read off Proxmox at registration and restated by every poll, so + // accepting a client's version of them would only let it disagree with + // the host. + ]; + + protected function casts(): array + { + return [ + 'size' => StorageSizeCast::class, + 'reserved_bytes' => StorageSizeCast::class, + 'pve_shared' => 'boolean', + ]; + } + + /** + * @return BelongsToMany + */ + public function nodes(): BelongsToMany + { + return $this->belongsToMany( + Node::class, + 'storage_to_node', + 'storage_id', + 'node_id', + ) + ->using(StorageToNode::class) + ->withPivot('backup_order', 'discovered_total', 'discovered_used', 'discovered_at'); + } + + /** + * @return BelongsTo + */ + public function cluster(): BelongsTo + { + return $this->belongsTo(Cluster::class); + } + + /** + * The last observed capacity, resolved per placement. + * + * The figures live on the (storage, node) links, so "how full is it" needs + * a node in scope. Given one, the answer is that link's own reading. Fleet + * wide it depends on the backend: a shared pool is one pool however many + * nodes read it, so the freshest reading stands for all of them; a local + * definition names a different disk on every node, so the readings sum -- + * and the sum is only as fresh as its stalest part, which is why `at` + * takes the oldest timestamp there. + * + * @return array{total: ?int, used: ?int, at: ?CarbonImmutable} + */ + public function recordedCapacity(?Node $node = null): array + { + $observed = $this->observedLinks() + ->filter(fn (StorageToNode $link) => $link->discovered_at !== null); + + if ($node !== null) { + $observed = $observed->where('node_id', $node->id); + } + + if ($observed->isEmpty()) { + return ['total' => null, 'used' => null, 'at' => null]; + } + + if ($node !== null || $this->pve_shared) { + /** @var StorageToNode $freshest */ + $freshest = $observed->sortByDesc('discovered_at')->first(); + + return [ + 'total' => (int) $freshest->discovered_total, + 'used' => (int) $freshest->discovered_used, + 'at' => $freshest->discovered_at, + ]; + } + + return [ + 'total' => (int) $observed->sum('discovered_total'), + 'used' => (int) $observed->sum('discovered_used'), + 'at' => $observed->min('discovered_at'), + ]; + } + + /** + * This storage's links, from the loaded relation when the caller eager + * loaded it (one query for a whole listing) and from a query when not. + * + * @return Collection + */ + private function observedLinks(): Collection + { + if ($this->relationLoaded('nodes')) { + return $this->nodes->map(fn (Node $node) => $node->pivot)->values(); + } + + return StorageToNode::query()->where('storage_id', $this->id)->get()->toBase(); + } + + /** + * Get the servers whose primary disk resides on this storage. + */ + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } + + /** + * Get the VM disks (primary and secondary) that reside on this storage. + * This is the disk-oriented source for "Allocated by Convoy" — a server + * can have disks on several storages, so we sum disk rows, not servers. + */ + public function serverDisks(): HasMany + { + return $this->hasMany(ServerDisk::class); + } + + /** + * Get the backups stored on this storage. + */ + public function backups(): HasMany + { + // Assumes 'storage_id' foreign key exists on the 'backups' table + return $this->hasMany(Backup::class); + } + + /** + * Query Scope to automatically include the sums of related storage usage. + * + * Call this like: Storage::withUsageSums()->find(1); + * + * @param Builder $query The Eloquent query builder. + */ + public function scopeWithUsageSums(Builder $query): void + { + $query->withSum('serverDisks as servers_sum_disk', 'size') + ->withSum('backups as backups_sum_size', 'size'); + } + + /** + * Helper method to get usage value, checking for pre-loaded sums first. + * + * @param string $relationshipName The name of the relationship method (e.g., 'servers'). + * @param string $sumColumn The column to sum on the related table (e.g., 'disk'). + * @param string $preloadedSumAttribute The expected attribute name if loaded via withSum (e.g., 'servers_sum_disk'). + */ + private function getUsageAttributeValue(string $relationshipName, string $sumColumn, string $preloadedSumAttribute): int + { + // withSum() sums the raw column, which is MiB, and never runs the cast + // that would have made it bytes -- so the scaling below is not a + // convenience, it is the cast being applied by hand. See StorageSizeCast. + if (array_key_exists($preloadedSumAttribute, $this->attributes)) { + // Return the preloaded value, defaulting to 0 if null + return ByteUnit::Mebibytes->toBytes((int) ($this->attributes[$preloadedSumAttribute] ?? 0)); // convert from MiB to bytes + } + + // Fallback: Calculate on the fly using the relationship method + // Warning: Can cause N+1 query issues if withSum wasn't used on collections + // Use Str::camel to call the relationship method dynamically (e.g., 'servers' -> $this->servers()) + $relationshipMethod = Str::camel($relationshipName); + if (method_exists($this, $relationshipMethod)) { + return ByteUnit::Mebibytes->toBytes((int) ($this->$relationshipMethod()->sum($sumColumn) ?? 0)); // convert from MiB to bytes + } + + // Return 0 if the relationship method doesn't exist (should not happen with the correct usage) + return 0; + } + + /** + * Accessor for server disk usage. + */ + public function getServerUsageAttribute(): int + { + return $this->getUsageAttributeValue('serverDisks', 'size', 'servers_sum_disk'); + } + + /** + * Accessor for backup size usage. + */ + public function getBackupUsageAttribute(): int + { + return $this->getUsageAttributeValue('backups', 'size', 'backups_sum_size'); + } + + /** + * Accessor for ISO size usage. + */ + /** + * Always zero, and deliberately so. + * + * ISOs are no longer placed on a storage by the panel: a node fetches one + * when someone mounts it, and the copy is a cache PVE owns. The panel has + * no record of which storages hold which ISOs, and inventing one would mean + * reporting an allocation nobody made. The real figure is the storage's own + * `used`, which PVE reports and which already includes them. + */ + public function getIsoUsageAttribute(): int + { + return 0; + } + + /** + * Whether PVE says this storage accepts a kind of content. + * + * Read off `pve_content` rather than a column per type, because the list is + * Proxmox's answer and it was already stored: keeping seven booleans beside + * it meant one fact written twice, and every new content type cost a + * migration plus five edits that could disagree with each other. + * + * A null list means "PVE has not told us yet", which is not the same as + * "holds nothing" -- but it still answers false, because a storage the + * panel cannot confirm is not one it should place anything on. + */ + public function stores(StorageContentType $type): bool + { + return StorageContentType::flagsFor($this->pve_content)[$type->toModelAttributeName()] ?? false; + } + + /** + * The same question, asked of the database. + * + * Matched against a delimited list rather than as a substring, so `iso` + * cannot be answered by a storage that only holds `vztmpl` -- the same trap + * {@see StorageContentType::flagsFor} exists to avoid in PHP. + */ + public function scopeStores(Builder $query, StorageContentType $type): void + { + $query->whereRaw( + "concat(',', coalesce(storages.pve_content, ''), ',') like ?", + ['%,'.$type->toProxmoxString().',%'], + ); + } + + public function getStoresKvmAttribute(): bool + { + return $this->stores(StorageContentType::KVM); + } + + public function getStoresLxcAttribute(): bool + { + return $this->stores(StorageContentType::LXC); + } + + public function getStoresLxcTemplatesAttribute(): bool + { + return $this->stores(StorageContentType::LXC_TEMPLATES); + } + + public function getStoresBackupsAttribute(): bool + { + return $this->stores(StorageContentType::BACKUPS); + } + + public function getStoresIsoAttribute(): bool + { + return $this->stores(StorageContentType::ISO); + } + + public function getStoresImportAttribute(): bool + { + return $this->stores(StorageContentType::IMPORT); + } + + public function getStoresSnippetsAttribute(): bool + { + return $this->stores(StorageContentType::SNIPPETS); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Models/StorageToNode.php b/app/Models/StorageToNode.php new file mode 100644 index 00000000000..661902afccf --- /dev/null +++ b/app/Models/StorageToNode.php @@ -0,0 +1,102 @@ + 'immutable_datetime', + ]; + } + + public array $sortable = [ + 'order_column_name' => 'backup_order', + 'sort_when_creating' => true, + ]; + + /** + * The set this row is ordered within: the backup storages of its own node. + * + * Scoped by `node_id` as well as by content type. Without it the sequence is + * global, so the next order number for a storage on one node is chosen by + * looking at every node's storages -- and a shared pool would share one + * position across all of them, which is not what backup order means. + */ + public function buildSortQuery(): Builder + { + return static::query() + ->where('node_id', $this->node_id) + ->whereHas('storage', function (Builder $query) { + $query->stores(StorageContentType::BACKUPS); + }); + } + + public function node(): BelongsTo + { + return $this->belongsTo(Node::class); + } + + public function storage(): BelongsTo + { + return $this->belongsTo(Storage::class); + } +} diff --git a/app/Models/SystemActor.php b/app/Models/SystemActor.php new file mode 100644 index 00000000000..11861fe9e8b --- /dev/null +++ b/app/Models/SystemActor.php @@ -0,0 +1,30 @@ +firstOrCreate([], ['name' => 'System']); + } +} diff --git a/app/Models/Template.php b/app/Models/Template.php deleted file mode 100644 index 24ac305183b..00000000000 --- a/app/Models/Template.php +++ /dev/null @@ -1,47 +0,0 @@ - 'required|integer|exists:template_groups,id', - 'name' => 'required|string|max:40', - 'vmid' => 'required|numeric|min:100|max:999999999', - 'hidden' => 'required|boolean', - ]; - - protected $guarded = [ - 'id', - 'order_column', - 'created_at', - 'updated_at', - ]; - - public function group(): BelongsTo - { - return $this->belongsTo(TemplateGroup::class, 'template_group_id'); - } - - public function buildSortQuery(): Builder - { - return static::query()->where('template_group_id', $this->template_group_id); - } - - protected static function boot(): void - { - parent::boot(); - - static::creating(function ($model) { - $model->uuid = Uuid::uuid4()->toString(); - }); - } -} diff --git a/app/Models/TemplateGroup.php b/app/Models/TemplateGroup.php deleted file mode 100644 index 6e079a5e717..00000000000 --- a/app/Models/TemplateGroup.php +++ /dev/null @@ -1,46 +0,0 @@ - 'required|integer|exists:nodes,id', - 'name' => 'required|string|max:40', - 'hidden' => 'sometimes|boolean', - ]; - - protected $guarded = [ - 'id', - 'order_column', - 'created_at', - 'updated_at', - ]; - - public function templates(): HasMany - { - return $this->hasMany(Template::class); - } - - public function buildSortQuery(): Builder - { - return static::query()->where('node_id', $this->node_id); - } - - protected static function boot(): void - { - parent::boot(); - - static::creating(function ($model) { - $model->uuid = Uuid::uuid4()->toString(); - }); - } -} diff --git a/app/Models/User.php b/app/Models/User.php index ced3e07e931..40e2e03899d 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -1,8 +1,8 @@ + * @var list */ protected $fillable = [ 'name', @@ -49,7 +57,7 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac /** * The attributes that should be hidden for serialization. * - * @var array + * @var list */ protected $hidden = [ 'password', @@ -61,18 +69,32 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac ]; /** - * The attributes that should be cast. + * Get the attributes that should be cast. * - * @var array + * @return array */ - protected $casts = [ - 'email_verified_at' => 'datetime', - 'root_admin' => 'boolean', - ]; + protected function casts(): array + { + return [ + 'email_verified_at' => 'datetime', + 'password' => 'hashed', + 'root_admin' => 'boolean', + ]; + } - public function toReactObject(): array + /** + * Where this account's picture is served from, or null when it has none. + * + * A path rather than a stored URL: the file lives on a swappable disk and + * the panel is what serves it, so the address is derived at read time. + */ + public function avatarUrl(): ?string { - return Collection::make($this->toArray())->except(['id'])->toArray(); + // `avatar_path` already carries the `avatars/` prefix the serving route + // matches on, so it is the whole path -- not a segment to prepend to. + return $this->avatar_path + ? url("/{$this->avatar_path}") + : null; } public function createToken( @@ -90,14 +112,73 @@ public function createToken( return new NewAccessToken($token, $token->getKey().'|'.$plainTextToken); } - public function tokens(): MorphMany + /** + * @return HasMany + */ + public function servers(): HasMany + { + return $this->hasMany(Server::class); + } + + /** + * The account's own API keys, as opposed to every token whose `tokenable` happens to be this + * row: an application token is minted by an admin against their own user but belongs to the + * panel, and nothing on the account surface can see or revoke it. + * + * Constrained on the relation rather than at each call site so that route scope-binding + * (`/users/{user}/api-keys/{apiKey}`) refuses an application token id with a 404. + * + * @return MorphMany + */ + public function apiKeys(): MorphMany { - return $this->morphMany(PersonalAccessToken::class, 'tokenable'); + return $this->morphMany(PersonalAccessToken::class, 'tokenable') + ->where('type', '=', ApiKeyType::ACCOUNT->value); } - public function servers(): HasMany + /** + * @return HasMany + */ + public function passkeys(): HasMany { - return $this->hasMany(Server::class); + return $this->hasMany(Passkey::class); + } + + /** A password login needs either supported second-factor method. */ + public function hasEnabledSecondFactor(): bool + { + return $this->hasEnabledTwoFactorAuthentication() || $this->passkeys()->exists(); + } + + public function getPassKeyName(): string + { + return $this->email; + } + + public function getPassKeyId(): string + { + return $this->uuid; + } + + public function getPassKeyDisplayName(): string + { + return $this->name; + } + + /** + * @return HasMany + */ + public function sshKeys(): HasMany + { + return $this->hasMany(SSHKey::class); + } + + /** + * @return HasMany + */ + public function oauthConnections(): HasMany + { + return $this->hasMany(OAuthConnection::class); } public function getRouteKeyName(): string diff --git a/app/Models/UserInvite.php b/app/Models/UserInvite.php new file mode 100644 index 00000000000..620d7ab13af --- /dev/null +++ b/app/Models/UserInvite.php @@ -0,0 +1,67 @@ + 'required|exists:users,id', + 'token' => 'required|string|size:64', + 'expires_at' => 'required|date', + ]; + + protected function casts(): array + { + return [ + 'expires_at' => 'immutable_datetime', + ]; + } + + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function hasExpired(): bool + { + return $this->expires_at->isPast(); + } + + /** + * Expired invites are excluded at the query rather than filtered afterwards, so a lapsed + * link is indistinguishable from one that never existed — the consume endpoint should not + * be able to tell an attacker which of the two they are holding. + */ + public function scopeUnexpired(Builder $query): Builder + { + return $query->where('expires_at', '>', CarbonImmutable::now()); + } +} diff --git a/app/Models/Vlan.php b/app/Models/Vlan.php new file mode 100644 index 00000000000..2902f57d3a7 --- /dev/null +++ b/app/Models/Vlan.php @@ -0,0 +1,55 @@ + 'required|integer|min:1|max:4094', + 'name' => 'nullable|string|max:40', + 'description' => 'nullable|string|max:191', + ]; + + protected function casts(): array + { + return [ + 'tag' => 'integer', + ]; + } + + public function networkInterface(): BelongsTo + { + return $this->belongsTo(NetworkInterface::class); + } + + public function getRouteKeyName(): string + { + return 'id'; + } +} diff --git a/app/Notifications/PasswordChanged.php b/app/Notifications/PasswordChanged.php new file mode 100644 index 00000000000..6d372aae3e5 --- /dev/null +++ b/app/Notifications/PasswordChanged.php @@ -0,0 +1,42 @@ + + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + public function toMail(object $notifiable): MailMessage + { + // The template decides whether the address gets a row, because whether + // it was recorded is a display question. Passing null through is enough. + return (new MailMessage) + ->subject('Your '.config('app.name').' password was changed') + ->view('mail.password-changed', [ + 'ipAddress' => $this->ipAddress, + ]); + } +} diff --git a/app/Notifications/UserInvited.php b/app/Notifications/UserInvited.php new file mode 100644 index 00000000000..1cebbca54f5 --- /dev/null +++ b/app/Notifications/UserInvited.php @@ -0,0 +1,50 @@ + + */ + public function via(object $notifiable): array + { + return ['mail']; + } + + public function toMail(object $notifiable): MailMessage + { + $days = $this->expiresInDays; + + // A built view rather than MailMessage's line/action builder: that + // builder renders through Laravel's markdown theme, which is the one + // thing in the app that does not use the panel's design tokens. See + // emails/ for the Maizzle project that compiles this template. + return (new MailMessage) + ->subject('Set up your '.config('app.name').' account') + ->view('mail.user-invited', [ + 'name' => $notifiable->name, + 'link' => $this->link, + 'expiry' => $days.' '.($days === 1 ? 'day' : 'days'), + ]); + } +} diff --git a/app/Policies/AddressBlockGroupPolicy.php b/app/Policies/AddressBlockGroupPolicy.php new file mode 100644 index 00000000000..8a2fcd3fc07 --- /dev/null +++ b/app/Policies/AddressBlockGroupPolicy.php @@ -0,0 +1,85 @@ +root_admin; + } + + public function detachNode(User $user, AddressBlockGroup $addressBlockGroup): Response + { + if (! $user->root_admin) { + return $this->deny('Only root admins can detach nodes.'); + } + + $nodeId = request()->route('node'); + + if (! $nodeId) { + // Fallback if node isn't resolved yet or passed differently, but usually it's in the route. + // If we can't find the node, we might allow (controller handles 404) or deny. + // However, for the specific check: + return $this->allow(); + } + + // We need to check if any server on this node is using an IP from this block group. + // The node is bound to the route as 'node' (which is the Node model or ID). + // Since we don't have the Node instance passed directly to the policy method signature + // (unless we add it, but standard policy usually takes User and Resource), + // we can fetch it or trust the controller to do the check. + // BUT, the user asked to do this check in the policy/request. + + // Let's resolve the node from the route if possible. + $node = request()->route('node'); + if (! ($node instanceof Node)) { + // If implicit binding hasn't happened yet or it's just an ID + $node = Node::find($node); + } + + if (! $node) { + return $this->allow(); // Let controller handle 404 + } + + // Check if any server on this node has an IP address that belongs to any block in this group. + $hasUsedIps = Server::where('node_id', $node->id) + ->whereHas('addresses.addressBlock', function ($query) use ($addressBlockGroup) { + $query->where('address_block_group_id', $addressBlockGroup->id); + }) + ->exists(); + + if ($hasUsedIps) { + return $this->deny('Cannot detach node because some servers on this node are using IP addresses from this block group.'); + } + + return $this->allow(); + } + + public function delete(User $user, AddressBlockGroup $addressBlockGroup): Response + { + $isInUse = $addressBlockGroup->addressBlocks() + ->whereHas('addresses', function ($query) { + $query->whereNotNull('server_id'); + }) + ->exists(); + + if ($isInUse) { + return $this->deny('This address block group cannot be deleted because it contains IP addresses currently assigned to servers.'); + } + + return $this->allow(); + } +} diff --git a/app/Policies/AddressBlockPolicy.php b/app/Policies/AddressBlockPolicy.php new file mode 100644 index 00000000000..0de34fa6e80 --- /dev/null +++ b/app/Policies/AddressBlockPolicy.php @@ -0,0 +1,26 @@ +addresses() + ->whereNotNull('server_id') + ->exists(); + + if ($isInUse) { + return $this->deny('This address block cannot be deleted because it contains IP addresses currently assigned to servers.'); + } + + return $this->allow(); + } +} diff --git a/app/Policies/BackupPolicy.php b/app/Policies/BackupPolicy.php index fc2cd3561f9..927fb2bb39d 100644 --- a/app/Policies/BackupPolicy.php +++ b/app/Policies/BackupPolicy.php @@ -1,15 +1,17 @@ root_admin || $user->id === $server->user_id) { return true; } diff --git a/app/Policies/CotermPolicy.php b/app/Policies/CotermPolicy.php deleted file mode 100644 index 88ce5b83fb0..00000000000 --- a/app/Policies/CotermPolicy.php +++ /dev/null @@ -1,23 +0,0 @@ -loadCount(['nodes']); - - if ($coterm->nodes_count > 0) { - $this->deny('Cannot delete an instance of Coterm with nodes attached to it.'); - } - - return true; - } -} diff --git a/app/Policies/NetworkInterfacePolicy.php b/app/Policies/NetworkInterfacePolicy.php new file mode 100644 index 00000000000..329875ac512 --- /dev/null +++ b/app/Policies/NetworkInterfacePolicy.php @@ -0,0 +1,14 @@ +root_admin; + } +} diff --git a/app/Policies/PasskeyPolicy.php b/app/Policies/PasskeyPolicy.php new file mode 100644 index 00000000000..c7503e1464c --- /dev/null +++ b/app/Policies/PasskeyPolicy.php @@ -0,0 +1,20 @@ +id === $passkey->user_id + ? Response::allow() + : Response::denyAsNotFound(); + } +} diff --git a/app/Policies/ServerPolicy.php b/app/Policies/ServerPolicy.php index d489e3abbc0..fd8cb895d89 100644 --- a/app/Policies/ServerPolicy.php +++ b/app/Policies/ServerPolicy.php @@ -1,9 +1,9 @@ app->scoped(ActivityLogBatchService::class); - $this->app->scoped(ActivityLogTargetableService::class); - } -} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b987a6162f9..5e551df19d0 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -1,13 +1,32 @@ isStarted()) { + SessionRecord::query() + ->where('session_id', $session->getId()) + ->delete(); + } + }); + + $this->bootRoute(); + $this->bootOidc(); + $this->bootMail(); + } + + /** + * Let the panel's stored SMTP settings override MAIL_* before anything resolves a mailer. + * + * Hooked to the mail manager rather than run at boot, for two reasons. It is a database read, + * and the overwhelming majority of requests never send anything — paying for it on every one + * of them buys nothing. And resolving settings during boot pins them before anything else in + * the process can have finished setting the database up, which is exactly how the first test + * in a suite ended up holding values from before its own migrations ran. + * + * The manager reads `config('mail.mailers.*')` when a mailer is built, not when the manager + * itself is constructed, so writing the config here lands in time. + * + * Deliberately swallowing everything: a panel that will not serve a request because it cannot + * look up its own mail configuration would be a far worse failure than one that falls back to + * the environment, which is exactly what skipping this does. + */ + public function bootMail(): void + { + $this->app->afterResolving(MailManager::class, function () { + try { + $this->app->make(MailConfigurator::class)->apply(); + } catch (\Throwable) { + // Environment stays in charge. + } + }); + } + + /** + * Register the generic OpenID Connect Socialite driver so operators can federate against + * any standards-compliant IdP by pointing `services.oidc.base_url` at its issuer. Socialite + * ships no such driver, so we extend it with our own {@see OidcProvider}. + */ + public function bootOidc(): void + { + $socialite = $this->app->make(Socialite::class); + + $socialite->extend('oidc', function () use ($socialite) { + $config = config('services.oidc', []); + + $provider = $socialite->buildProvider(OidcProvider::class, $config); + + // OIDC scopes are operator-tunable (some IdPs want extra scopes to release claims), + // but `openid` is mandatory. setScopes fully replaces the driver defaults so operators + // retain control; we just fold `openid` back in unconditionally. + $scopes = array_values(array_unique(array_merge( + ['openid'], + (array) ($config['scopes'] ?? ['profile', 'email']), + ))); + + return $provider->setScopes($scopes); + }); + } + + public function bootRoute(): void + { + // Passkey extends the spatie/laravel-passkeys model (required by the package's + // config), which sidesteps Laravel's implicit route-model binding — so bind it + // explicitly, like `server` below. + Route::bind('passkey', fn (string $value) => Passkey::query()->findOrFail($value)); + + Route::bind('server', function (string $value) { + + return Server::query() + ->where(strlen($value) === 8 ? 'uuid_short' : 'uuid', $value) + // Only match by id for numeric values; postgres errors casting a + // uuid string to the bigint id column. + ->when(is_numeric($value), fn ($query) => $query->orWhere('id', $value)) + ->firstOrFail(); + }); } } diff --git a/app/Providers/AuditServiceProvider.php b/app/Providers/AuditServiceProvider.php new file mode 100644 index 00000000000..0ad4c9c556b --- /dev/null +++ b/app/Providers/AuditServiceProvider.php @@ -0,0 +1,28 @@ +app->scoped(AuditLogger::class); + } + + /** + * Registered explicitly: Laravel auto-discovers plain listeners, but not subscribers. + */ + public function boot(): void + { + Event::subscribe(AuditAuthenticationSubscriber::class); + } +} diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php deleted file mode 100644 index fdfaae6887b..00000000000 --- a/app/Providers/AuthServiceProvider.php +++ /dev/null @@ -1,25 +0,0 @@ - - */ - protected $policies = [ - // 'Convoy\Models\Model' => 'Convoy\Policies\ModelPolicy', - ]; - - /** - * Register any authentication / authorization services. - */ - public function boot(): void - { - // - } -} diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php deleted file mode 100644 index fff804a00c7..00000000000 --- a/app/Providers/BroadcastServiceProvider.php +++ /dev/null @@ -1,19 +0,0 @@ -> - */ - protected $listen = [ - Registered::class => [ - SendEmailVerificationNotification::class, - ], - ]; - - /** - * Register any events for your application. - */ - public function boot(): void - { - // - } - - /** - * Determine if events and listeners should be automatically discovered. - */ - public function shouldDiscoverEvents(): bool - { - return false; - } -} diff --git a/app/Providers/FortifyServiceProvider.php b/app/Providers/FortifyServiceProvider.php index ea778c3377e..0250d020d80 100644 --- a/app/Providers/FortifyServiceProvider.php +++ b/app/Providers/FortifyServiceProvider.php @@ -1,16 +1,24 @@ app->bind(EnableTwoFactorAuthentication::class, EnableAuthenticator::class); + $this->app->bind(DisableTwoFactorAuthentication::class, DisableAuthenticator::class); + // Fortify's challenge controller type-hints the parent, so the binding is + // what gets our subclass injected. See SecondFactorLoginRequest. + $this->app->bind(TwoFactorLoginRequest::class, SecondFactorLoginRequest::class); } /** @@ -27,11 +39,17 @@ public function register(): void */ public function boot(): void { - Fortify::createUsersUsing(CreateNewUser::class); - Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class); - Fortify::updateUserPasswordsUsing(UpdateUserPassword::class); - Fortify::resetUserPasswordsUsing(ResetUserPassword::class); - //Fortify::ignoreRoutes(); + Fortify::ignoreRoutes(); + + Fortify::authenticateThrough(fn () => array_filter([ + config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class, + config('fortify.lowercase_usernames') ? CanonicalizeUsername::class : null, + Features::enabled(Features::twoFactorAuthentication()) + ? RedirectIfSecondFactorAuthenticatable::class + : null, + AttemptToAuthenticate::class, + PrepareAuthenticatedSession::class, + ])); RateLimiter::for('login', function (Request $request) { $email = (string) $request->email; diff --git a/app/Providers/HorizonServiceProvider.php b/app/Providers/HorizonServiceProvider.php index 9b0a34d0d6b..949c6f354df 100644 --- a/app/Providers/HorizonServiceProvider.php +++ b/app/Providers/HorizonServiceProvider.php @@ -1,6 +1,6 @@ app->bind(ActivityRepositoryInterface::class, ActivityRepository::class); - } -} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php deleted file mode 100644 index 741bc975c1d..00000000000 --- a/app/Providers/RouteServiceProvider.php +++ /dev/null @@ -1,66 +0,0 @@ -where(strlen($value) === 8 ? 'uuid_short' : 'uuid', $value) - ->firstOrFail(); - }); - - $this->routes(function () { - Route::middleware('web')->group(function () { - Route::middleware('guest')->group(base_path('routes/auth.php')); - - Route::middleware(['auth.session']) - ->group(base_path('routes/base.php')); - - Route::middleware(['auth'])->prefix('/api/client') - ->as('client.') - ->scopeBindings() - ->group(base_path('routes/api-client.php')); - - Route::middleware(['auth', AdminAuthenticate::class]) - ->prefix('/api/admin') - ->as('admin.') - ->scopeBindings() - ->group(base_path('routes/api-admin.php')); - }); - - Route::middleware(['api'])->group(function () { - Route::middleware(['auth:sanctum', AdminAuthenticate::class]) - ->prefix('/api/application') - ->as('application.') - ->scopeBindings() - ->group(base_path('routes/api-application.php')); - - Route::middleware([CotermAuthenticate::class]) - ->prefix('/api/coterm') - ->as('coterm.') - ->scopeBindings() - ->group(base_path('routes/api-coterm.php')); - }); - }); - } -} diff --git a/app/Providers/TypeScriptTransformerServiceProvider.php b/app/Providers/TypeScriptTransformerServiceProvider.php new file mode 100644 index 00000000000..e212b05d9c7 --- /dev/null +++ b/app/Providers/TypeScriptTransformerServiceProvider.php @@ -0,0 +1,43 @@ +extension(new LaravelDataTypeScriptTransformerExtension) + ->transformer(EnumTransformer::class) + ->transformDirectories( + app_path('Data'), + app_path('Enums'), + ) + ->outputDirectory(resource_path('scripts/types')) + ->writer(new GlobalNamespaceWriter('generated.d.ts')) + ->formatter(PrettierFormatter::class); + + // Types referenced by Data classes that live outside the transformed + // directories (Eloquent models, third-party interfaces) can't resolve on + // their own — without these the transform logs "not found in the + // transformed types" warnings and falls back to `any` anyway. IPLib + // addresses/ranges serialize to strings; the raw models are passed + // through untyped. + $config + ->replaceType(AddressInterface::class, 'string') + ->replaceType(RangeInterface::class, 'string') + ->replaceType(Address::class, 'any') + ->replaceType(Deployment::class, 'any'); + } +} diff --git a/app/Repositories/Eloquent/ActivityRepository.php b/app/Repositories/Eloquent/ActivityRepository.php deleted file mode 100644 index 5b17a3876f1..00000000000 --- a/app/Repositories/Eloquent/ActivityRepository.php +++ /dev/null @@ -1,20 +0,0 @@ -subjects()->firstWhere('subject_type', (new Server)->getMorphClass())?->subject()->first(); - } -} diff --git a/app/Repositories/Eloquent/AddressRepository.php b/app/Repositories/Eloquent/AddressRepository.php deleted file mode 100644 index 7b2f19b6ede..00000000000 --- a/app/Repositories/Eloquent/AddressRepository.php +++ /dev/null @@ -1,43 +0,0 @@ -id, - ...$addressIds, - $server->node_id, - ]); - } -} \ No newline at end of file diff --git a/app/Repositories/Eloquent/BackupRepository.php b/app/Repositories/Eloquent/BackupRepository.php deleted file mode 100644 index bb48e150f24..00000000000 --- a/app/Repositories/Eloquent/BackupRepository.php +++ /dev/null @@ -1,44 +0,0 @@ -getBuilder() - ->withTrashed() - ->where('server_id', $server) - ->where(function ($query) { - $query->whereNull('completed_at') - ->orWhere('is_successful', '=', true); - }) - ->where('created_at', '>=', Carbon::now()->subSeconds($seconds)->toDateTimeString()) - ->get() - ->toBase(); - } - - public function getNonFailedBackups(Server $server): HasMany - { - return $server->backups()->where(function ($query) { - $query->whereNull('completed_at') - ->orWhere('is_successful', true); - }); - } -} diff --git a/app/Repositories/Eloquent/EloquentRepository.php b/app/Repositories/Eloquent/EloquentRepository.php deleted file mode 100644 index 6fdedea1a7a..00000000000 --- a/app/Repositories/Eloquent/EloquentRepository.php +++ /dev/null @@ -1,315 +0,0 @@ -useRequestFilters = $usingFilters; - - return $this; - } - - /** - * Returns the request instance. - * - * @return Request - */ - protected function request() - { - return $this->app->make(Request::class); - } - - /** - * Paginate the response data based on the page para. - * - * @return LengthAwarePaginator - */ - protected function paginate(Builder $instance, int $default = 50) - { - if (! $this->useRequestFilters) { - return $instance->paginate($default); - } - - return $instance->paginate($this->request()->query('per_page', $default)); - } - - /** - * Return an instance of the eloquent model bound to this - * repository instance. - */ - public function getModel(): Model - { - return $this->model; - } - - /** - * Return an instance of the builder to use for this repository. - * - * @return Builder - */ - public function getBuilder() - { - return $this->getModel()->newQuery(); - } - - /** - * Create a new record in the database and return the associated model. - * - * @return Model|bool - * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - */ - public function create(array $fields, bool $validate = true, bool $force = false) - { - $instance = $this->getBuilder()->newModelInstance(); - ($force) ? $instance->forceFill($fields) : $instance->fill($fields); - - if (! $validate) { - $saved = $instance->skipValidation()->save(); - } else { - if (! $saved = $instance->save()) { - throw new DataValidationException($instance->getValidator(), $instance); - } - } - - return ($this->withFresh) ? $instance->fresh() : $saved; - } - - /** - * Find a model that has the specific ID passed. - * - * @return Model - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function find(int $id) - { - try { - return $this->getBuilder()->findOrFail($id, $this->getColumns()); - } catch (ModelNotFoundException $exception) { - throw new RecordNotFoundException(); - } - } - - /** - * Find a model matching an array of where clauses. - */ - public function findWhere(array $fields): Collection - { - return $this->getBuilder()->where($fields)->get($this->getColumns()); - } - - /** - * Find and return the first matching instance for the given fields. - * - * @return Model - * - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function findFirstWhere(array $fields) - { - try { - return $this->getBuilder()->where($fields)->firstOrFail($this->getColumns()); - } catch (ModelNotFoundException $exception) { - throw new RecordNotFoundException(); - } - } - - /** - * Return a count of records matching the passed arguments. - */ - public function findCountWhere(array $fields): int - { - return $this->getBuilder()->where($fields)->count($this->getColumns()); - } - - /** - * Delete a given record from the database. - */ - public function delete(int $id, bool $destroy = false): int - { - return $this->deleteWhere(['id' => $id], $destroy); - } - - /** - * Delete records matching the given attributes. - */ - public function deleteWhere(array $attributes, bool $force = false): int - { - $instance = $this->getBuilder()->where($attributes); - - return ($force) ? $instance->forceDelete() : $instance->delete(); - } - - /** - * Update a given ID with the passed array of fields. - * - * @param int $id - * @return Model|bool - * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function update($id, array $fields, bool $validate = true, bool $force = false) - { - try { - $instance = $this->getBuilder()->where('id', $id)->firstOrFail(); - } catch (ModelNotFoundException $exception) { - throw new RecordNotFoundException(); - } - - ($force) ? $instance->forceFill($fields) : $instance->fill($fields); - - if (! $validate) { - $saved = $instance->skipValidation()->save(); - } else { - if (! $saved = $instance->save()) { - throw new DataValidationException($instance->getValidator(), $instance); - } - } - - return ($this->withFresh) ? $instance->fresh() : $saved; - } - - /** - * Update a model using the attributes passed. - * - * @param array|Closure $attributes - * @return int - */ - public function updateWhere($attributes, array $values) - { - return $this->getBuilder()->where($attributes)->update($values); - } - - /** - * Perform a mass update where matching records are updated using whereIn. - * This does not perform any model data validation. - */ - public function updateWhereIn(string $column, array $values, array $fields): int - { - Assert::notEmpty($column, 'First argument passed to updateWhereIn must be a non-empty string.'); - - return $this->getBuilder()->whereIn($column, $values)->update($fields); - } - - /** - * Update a record if it exists in the database, otherwise create it. - * - * @return Model - * - * @throws \Pterodactyl\Exceptions\Model\DataValidationException - * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException - */ - public function updateOrCreate(array $where, array $fields, bool $validate = true, bool $force = false) - { - foreach ($where as $item) { - Assert::true(is_scalar($item) || is_null($item), 'First argument passed to updateOrCreate should be an array of scalar or null values, received an array value of %s.'); - } - - try { - $instance = $this->setColumns('id')->findFirstWhere($where); - } catch (RecordNotFoundException $exception) { - return $this->create(array_merge($where, $fields), $validate, $force); - } - - return $this->update($instance->id, $fields, $validate, $force); - } - - /** - * Return all records associated with the given model. - * - * @deprecated Just use the model - */ - public function all(): Collection - { - return $this->getBuilder()->get($this->getColumns()); - } - - /** - * Return a paginated result set using a search term if set on the repository. - */ - public function paginated(int $perPage): LengthAwarePaginator - { - return $this->getBuilder()->paginate($perPage, $this->getColumns()); - } - - /** - * Insert a single or multiple records into the database at once skipping - * validation and mass assignment checking. - */ - public function insert(array $data): bool - { - return $this->getBuilder()->insert($data); - } - - /** - * Insert multiple records into the database and ignore duplicates. - */ - public function insertIgnore(array $values): bool - { - if (empty($values)) { - return true; - } - - foreach ($values as $key => $value) { - ksort($value); - $values[$key] = $value; - } - - $bindings = array_values(array_filter(array_flatten($values, 1), function ($binding) { - return ! $binding instanceof Expression; - })); - - $grammar = $this->getBuilder()->toBase()->getGrammar(); - $table = $grammar->wrapTable($this->getModel()->getTable()); - $columns = $grammar->columnize(array_keys(reset($values))); - - $parameters = collect($values)->map(function ($record) use ($grammar) { - return sprintf('(%s)', $grammar->parameterize($record)); - })->implode(', '); - - $statement = "insert ignore into $table ($columns) values $parameters"; - - return $this->getBuilder()->getConnection()->statement($statement, $bindings); - } - - /** - * Get the amount of entries in the database. - * - * @deprecated just use the count method off a model - */ - public function count(): int - { - return $this->getBuilder()->count(); - } -} diff --git a/app/Repositories/Eloquent/ServerRepository.php b/app/Repositories/Eloquent/ServerRepository.php deleted file mode 100644 index 70ee2d374d0..00000000000 --- a/app/Repositories/Eloquent/ServerRepository.php +++ /dev/null @@ -1,55 +0,0 @@ -getBuilder() - ->where('vmid', '=', $vmid) - ->where('node_id', '=', $nodeId) - ->exists(); - } - - /** - * Check if a given UUID and UUID-Short string are unique to a server. - */ - public function isUniqueUuidCombo(string $uuid, string $short): bool - { - return !$this->getBuilder()->where('uuid', '=', $uuid)->orWhere('uuid_short', '=', $short) - ->exists(); - } - - /** - * Return a server by UUID. - * - * @throws RecordNotFoundException - */ - public function getByUuid(string $uuid): Server - { - try { - /** @var Server $model */ - $model = $this->getBuilder() - ->where(function (Builder $query) use ($uuid) { - $query->where('uuid_short', $uuid)->orWhere('uuid', $uuid); - }) - ->firstOrFail($this->getColumns()); - - return $model; - } catch (ModelNotFoundException $exception) { - throw new RecordNotFoundException(); - } - } -} diff --git a/app/Repositories/Proxmox/Node/ProxmoxAccessRepository.php b/app/Repositories/Proxmox/Node/ProxmoxAccessRepository.php deleted file mode 100644 index 41264a7e776..00000000000 --- a/app/Repositories/Proxmox/Node/ProxmoxAccessRepository.php +++ /dev/null @@ -1,101 +0,0 @@ - - */ - public function getUsers(): Collection - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient() - ->get('/api2/json/access/users') - ->json(); - - $users = array_map(fn ($user) => UserData::fromRaw($user), $this->getData($response)); - - return collect($users); - } - - public function createUser(CreateUserData $data): CreateUserData - { - Assert::isInstanceOf($this->node, Node::class); - - $payload = [ - 'enable' => $data->enabled, - 'userid' => ($data->username ?? 'convoy-'.Str::random(53)).'@'.$data->realm_type->value, - 'password' => $data->password ?? Str::random(64), - 'expire' => $data->expires_at?->timestamp ?? false, - ]; - - $this->getHttpClient() - ->post('/api2/json/access/users', $payload) - ->json(); - - return CreateUserData::from([ - 'username' => explode('@', $payload['userid'])[0], - 'realm_type' => $data->realm_type, - 'password' => $payload['password'], - 'enabled' => $payload['enable'], - 'expires_at' => $data->expires_at, - ]); - } - - public function deleteUser(string $id, RealmType $realmType) - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'user' => $id.'@'.$realmType->value, - ]) - ->delete('/api2/json/access/users/{user}') - ->json(); - - return $this->getData($response); - } - - public function createRole(string $name, string $privileges) - { - Assert::isInstanceOf($this->node, Node::class); - - $payload = [ - 'roleid' => $name, - 'privs' => $privileges, - ]; - - $response = $this->getHttpClient() - ->post('/api2/json/access/roles', $payload) - ->json(); - - return $this->getData($response); - } - - public function createUserCredentials(RealmType $realmType, string $userid, string $password): UserCredentialsData - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient(shouldAuthorize: false) - ->post('/api2/json/access/ticket', [ - 'username' => $userid, - 'password' => $password, - 'realm' => $realmType->value, - ]) - ->json(); - - return UserCredentialsData::fromRaw($this->getData($response)); - } -} diff --git a/app/Repositories/Proxmox/Node/ProxmoxStorageRepository.php b/app/Repositories/Proxmox/Node/ProxmoxStorageRepository.php deleted file mode 100644 index 5d652af9576..00000000000 --- a/app/Repositories/Proxmox/Node/ProxmoxStorageRepository.php +++ /dev/null @@ -1,133 +0,0 @@ -node, Node::class); - Assert::regex($link, '/^(http|https):\/\//'); - - $payload = [ - 'content' => $contentType->value, - 'filename' => $fileName, - 'url' => $link, - 'verify-certificates' => $verifyCertificates, - ]; - - if ($checksumData) { - $payload['checksum'] = $checksumData->checksum; - $payload['algorithm'] = $checksumData->algorithm->value; - } - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'storage' => $this->node->iso_storage, - ]) - ->post('/api2/json/nodes/{node}/storage/{storage}/download-url', $payload) - ->json(); - - return $this->getData($response); - } - - public function deleteFile(ContentType $contentType, string $fileName) - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'storage' => $this->node->iso_storage, - 'file' => "{$this->node->iso_storage}:$contentType->value/$fileName", - ]) - ->delete('/api2/json/nodes/{node}/storage/{storage}/content/{file}') - ->json(); - - return $this->getData($response); - } - - /** - * @return Collection - */ - public function getIsos(): Collection - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'storage' => $this->node->iso_storage, - ]) - ->get('/api2/json/nodes/{node}/storage/{storage}/content?content=iso') - ->json(); - - $response = $this->getData($response); - - $isos = []; - - foreach ($response as $iso) { - $isos[] = IsoData::from([ - 'file_name' => explode('/', $iso['volid'])[1], - 'size' => $iso['size'], - 'created_at' => CarbonImmutable::createFromTimestamp($iso['ctime']), - ]); - } - - return collect($isos); - } - - public function getFileMetadata(string $link, bool $verifyCertificates = true): FileMetaData - { - Assert::isInstanceOf($this->node, Node::class); - Assert::regex($link, '/^(http|https):\/\//'); - - try { - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - ]) - ->get('/api2/json/nodes/{node}/query-url-metadata', [ - 'url' => $link, - 'verify-certificates' => $verifyCertificates, - ]) - ->json(); - } catch (ProxmoxConnectionException $e) { - if (str_contains($e->getMessage(), "Can't connect to")) { - throw new InvalidIsoLinkException(); - } - } - - if (Arr::get($response, 'success', 1) !== 1) { - throw new InvalidIsoLinkException(); - } - - $data = $this->getData($response); - - return FileMetaData::from([ - 'file_name' => $data['filename'], - 'mime_type' => $data['mimetype'], - 'size' => $data['size'], - ]); - } -} diff --git a/app/Repositories/Proxmox/ProxmoxRepository.php b/app/Repositories/Proxmox/ProxmoxRepository.php deleted file mode 100644 index cb02cb9a295..00000000000 --- a/app/Repositories/Proxmox/ProxmoxRepository.php +++ /dev/null @@ -1,88 +0,0 @@ -server = clone $server; - - $this->setNode($this->server->node); - - return $this; - } - - /** - * Set the node model this request is stemming from. - * - * @return $this - */ - public function setNode(Node $node): static - { - $this->node = $node; - - return $this; - } - - /** - * Removes the extra data property from the Proxmox API response - * - * @return mixed - */ - public function getData(array|string $response): mixed - { - return $response['data'] ?? $response; - } - - /** - * Return an instance of the Guzzle HTTP Client to be used for requests. - */ - public function getHttpClient( - array $headers = [], array $options = [], bool $shouldAuthorize = true, - ): PendingRequest - { - Assert::isInstanceOf($this->node, Node::class); - - return Http::withOptions(array_merge([ - 'verify' => $this->node->verify_tls, - 'base_uri' => "https://{$this->node->fqdn}:{$this->node->port}/", - 'timeout' => config('convoy.guzzle.timeout'), - 'connect_timeout' => config('convoy.guzzle.connect_timeout'), - 'headers' => array_merge([ - 'Authorization' => $shouldAuthorize ? "PVEAPIToken={$this->node->token_id}={$this->node->secret}" : null, - 'Accept' => 'application/json', - 'Content-Type' => 'application/json', - 'User-Agent' => null, - ], $headers), - ], $options))->throw(function (Response $response, RequestException $exception) { - throw new ProxmoxConnectionException($response, $exception); - }); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxActivityRepository.php b/app/Repositories/Proxmox/Server/ProxmoxActivityRepository.php deleted file mode 100644 index 0c7ab27a458..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxActivityRepository.php +++ /dev/null @@ -1,73 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - ]) - ->get('/api2/json/nodes/{node}/tasks', ['vmid' => $this->server->vmid, 'start' => $startAt, 'limit' => $limitRows]) - ->json(); - - return $this->getData($response); - } - - public function getStatus(string $upid) - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'task' => $upid, - ]) - ->get('/api2/json/nodes/{node}/tasks/{task}/status') - ->json(); - - return $this->getData($response); - } - - public function getLog(string $upid, int $startAt = 0, int $limitLinesTo = 100) - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'task' => $upid, - ]) - ->get('/api2/json/nodes/{node}/tasks/{task}/log', [ - 'start' => $startAt, - 'limit' => $limitLinesTo, - ]) - ->json(); - - return $this->getData($response); - } - - public function delete(string $upid) - { - Assert::isInstanceOf($this->node, Node::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'task' => $upid, - ]) - ->delete('/api2/json/nodes/{node}/tasks/{task}') - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxBackupRepository.php b/app/Repositories/Proxmox/Server/ProxmoxBackupRepository.php deleted file mode 100644 index 5a489868a54..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxBackupRepository.php +++ /dev/null @@ -1,93 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'storage' => $this->node->backup_storage, - ]) - ->get('/api2/json/nodes/{node}/storage/{storage}/content', [ - 'content' => 'backup', - 'vmid' => $this->server->vmid, - ]) - ->json(); - - return $this->getData($response); - } - - public function backup(BackupMode $mode, BackupCompressionType $compressionType) - { - Assert::isInstanceOf($this->server, Server::class); - - switch ($mode) { - case BackupMode::KILL: - $parsedMode = 'stop'; - break; - default: - $parsedMode = $mode->value; - break; - } - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - ]) - ->post('/api2/json/nodes/{node}/vzdump', [ - 'vmid' => $this->server->vmid, - 'storage' => $this->node->backup_storage, - 'mode' => $parsedMode, - 'compress' => $compressionType === BackupCompressionType::NONE ? (int)false : $compressionType->value, - ]) - ->json(); - - return $this->getData($response); - } - - public function restore(Backup $backup) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - ]) - ->post('/api2/json/nodes/{node}/qemu', [ - 'vmid' => $this->server->vmid, - 'force' => true, - 'archive' => "{$this->node->backup_storage}:backup/{$backup->file_name}", - ]) - ->json(); - - return $this->getData($response); - } - - public function delete(Backup $backup) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'storage' => $this->node->backup_storage, - 'backup' => "{$this->node->backup_storage}:backup/{$backup->file_name}", - ]) - ->delete('/api2/json/nodes/{node}/storage/{storage}/content/{backup}') - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxCloudinitRepository.php b/app/Repositories/Proxmox/Server/ProxmoxCloudinitRepository.php deleted file mode 100644 index da6920e44c4..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxCloudinitRepository.php +++ /dev/null @@ -1,46 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/config') - ->json(); - - return $this->getData($response); - } - - public function update(array $params = []) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/config', $params) - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxConfigRepository.php b/app/Repositories/Proxmox/Server/ProxmoxConfigRepository.php deleted file mode 100644 index 4bb554b9338..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxConfigRepository.php +++ /dev/null @@ -1,63 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/config') - ->json(); - - $unparsed = $this->getData($response); - $parsed = []; - - foreach ($unparsed as $key => $value) { - $parsed[] = [ - 'key' => $key, - 'value' => $value, - ]; - } - - return $parsed; - } - - public function getResources() - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->get('/api2/json/cluster/resources') - ->json(); - - $data = $this->getData($response); - - return collect($data)->where('vmid', $this->server->vmid)->firstOrFail(); - } - - public function update(array $payload = [], bool $put = false) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/config', $payload) - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxConsoleRepository.php b/app/Repositories/Proxmox/Server/ProxmoxConsoleRepository.php deleted file mode 100644 index bca6973233a..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxConsoleRepository.php +++ /dev/null @@ -1,75 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient(headers: [ - 'CSRFPreventionToken' => $credentials->csrf_token - ], options: [ - 'cookies' => CookieJar::fromArray([ - 'PVEAuthCookie' => $credentials->ticket, - ], $this->node->fqdn) - ], shouldAuthorize: false) - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/vncproxy', [ - 'websocket' => true - ]) - ->json(); - - $response = $this->getData($response); - - return NoVncCredentialsData::from([ - 'port' => $response['port'], - 'ticket' => $response['ticket'], - 'pve_auth_cookie' => $credentials->ticket, - ]); - } - - public function createXTermjsCredentials(UserCredentialsData $credentials): XTermCredentialsData - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient(headers: [ - 'CSRFPreventionToken' => $credentials->csrf_token - ], options: [ - 'cookies' => CookieJar::fromArray([ - 'PVEAuthCookie' => $credentials->ticket, - ], $this->node->fqdn) - ], shouldAuthorize: false) - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/termproxy', [ - 'vmid' => $this->server->vmid // this is to fix the "NOT A HASH REFERENCE" stupid error Proxmox has if there's no JSON body - // bruh fix ur shit proxmox - ]) - ->json(); - - $response = $this->getData($response); - - return XTermCredentialsData::from([ - 'port' => $response['port'], - 'ticket' => $response['ticket'], - 'username' => $credentials->username, - 'realm_type' => $credentials->realm_type, - 'pve_auth_cookie' => $credentials->ticket, - ]); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxDiskRepository.php b/app/Repositories/Proxmox/Server/ProxmoxDiskRepository.php deleted file mode 100644 index 636ab110a11..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxDiskRepository.php +++ /dev/null @@ -1,31 +0,0 @@ -server, Server::class); - - $kibibytes = floor($bytes / 1024); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->put('/api2/json/nodes/{node}/qemu/{server}/resize', [ - 'disk' => $disk->value, - 'size' => "{$kibibytes}K", - ]) - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxFirewallRepository.php b/app/Repositories/Proxmox/Server/ProxmoxFirewallRepository.php deleted file mode 100644 index 4dc0cf7f47f..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxFirewallRepository.php +++ /dev/null @@ -1,127 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->put('/api2/json/nodes/{node}/qemu/{server}/firewall/options', $payload) - ->json(); - - return $this->getData($response); - } - - public function getIpsets() - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset') - ->json(); - - return $this->getData($response); - } - - public function createIpset(string $name, string $comments = 'Generated by Convoy') - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset', [ - 'name' => $name, - 'comment' => $comments, - ]) - ->json(); - - return $this->getData($response); - } - - public function deleteIpset(string $name) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - 'ipset' => $name, - ]) - ->delete('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}') - ->json(); - - return $this->getData($response); - } - - public function getLockedIps(string $ipset) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - 'ipset' => $ipset, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}') - ->json(); - - return $this->getData($response); - } - - public function lockIp(string $ipset, string $address, string $comments = 'Generated by Convoy') - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - 'ipset' => $ipset, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}', [ - 'cidr' => $address, - 'nomatch' => false, - 'comment' => $comments, - ]) - ->json(); - - return $this->getData($response); - } - - public function unlockIp(string $ipset, string $address) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - 'ipset' => $ipset, - 'address' => $address, - ]) - ->delete('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}/{address}') - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php b/app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php deleted file mode 100644 index d9752f5f2b4..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxGuestAgentRepository.php +++ /dev/null @@ -1,61 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/agent/get-osinfo') - ->json(); - - return $this->getData($response); - } - - /** - * Update Guest Agent password for Administrator user. - * - * @param string $password - * @return mixed - * - * @throws ProxmoxConnectionException - */ - public function updateGuestAgentPassword(string $username, string $password) - { - Assert::isInstanceOf($this->server, Server::class); - - $params = [ - 'username' => $username, - 'password' => $password, - ]; - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/agent/set-user-password', $params) - ->json(); - - return $this->getData($response); - } -} \ No newline at end of file diff --git a/app/Repositories/Proxmox/Server/ProxmoxMetricsRepository.php b/app/Repositories/Proxmox/Server/ProxmoxMetricsRepository.php deleted file mode 100644 index 03d036de65c..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxMetricsRepository.php +++ /dev/null @@ -1,36 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/rrddata', [ - 'timeframe' => $timeframe->value, - 'cf' => $parameter->value, - ]) - ->json(); - - return Arr::map($this->getData($response), function (array $metric) { - $metric['netin'] = array_key_exists('netin', $metric) ? intval(floor($metric['netin'])) : 0; - $metric['netout'] = array_key_exists('netout', $metric) ? intval(floor($metric['netout'])) : 0; - - return $metric; - }); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxPowerRepository.php b/app/Repositories/Proxmox/Server/ProxmoxPowerRepository.php deleted file mode 100644 index f00177d7ee1..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxPowerRepository.php +++ /dev/null @@ -1,54 +0,0 @@ -server, Server::class); - - // I added this because I don't like the naming scheme Proxmox has - switch ($action) { - case PowerAction::RESTART: - $parsedAction = 'reboot'; - break; - case PowerAction::RESET: - $parsedAction = 'reset'; - break; - case PowerAction::RESUME: - $parsedAction = 'resume'; - break; - case PowerAction::SHUTDOWN: - $parsedAction = 'shutdown'; - break; - case PowerAction::START: - $parsedAction = 'start'; - break; - case PowerAction::KILL: - $parsedAction = 'stop'; - break; - case PowerAction::SUSPEND: - $parsedAction = 'suspend'; - break; - } - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - 'action' => $parsedAction, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/status/{action}', [ - ...($parsedAction !== 'suspend' ? ['timeout' => 30] : ['skiplock' => false]), - ]) - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxServerRepository.php b/app/Repositories/Proxmox/Server/ProxmoxServerRepository.php deleted file mode 100644 index 79d7ac656ab..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxServerRepository.php +++ /dev/null @@ -1,87 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/status/current') - ->json(); - - return ServerStateData::fromRaw($this->getData($response)); - } - - public function create(Template $template) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'template' => $template->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{template}/clone', [ - 'storage' => $this->node->vm_storage, - 'target' => $this->node->cluster, - 'newid' => $this->server->vmid, - 'full' => true, - ]) - ->json(); - - return $this->getData($response); - } - - public function delete() - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient(options: [ - 'query' => [ - 'destroy-unreferenced-disks' => true, - 'purge' => true, - ], - ]) - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->delete('/api2/json/nodes/{node}/qemu/{server}') - ->json(); - - return $this->getData($response); - } - - public function addUser(RealmType $realmType, string $userId, string $roleId) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->put('/api2/json/access/acl', [ - 'path' => '/vms/' . $this->server->vmid, - 'users' => $userId . '@' . $realmType->value, - 'roles' => $roleId, - ]) - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Proxmox/Server/ProxmoxSnapshotRepository.php b/app/Repositories/Proxmox/Server/ProxmoxSnapshotRepository.php deleted file mode 100644 index 9aefce3d409..00000000000 --- a/app/Repositories/Proxmox/Server/ProxmoxSnapshotRepository.php +++ /dev/null @@ -1,74 +0,0 @@ -server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->get('/api2/json/nodes/{node}/qemu/{server}/snapshot') - ->json(); - - return $this->getData($response); - } - - public function create(string $name) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/snapshot', [ - 'snapname' => $name, - ]) - ->json(); - - return $this->getData($response); - } - - public function restore(string $name) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - 'snapshot' => $name, - ]) - ->post('/api2/json/nodes/{node}/qemu/{server}/snapshot/{snapshot}/rollback') - ->json(); - - return $this->getData($response); - } - - public function delete(string $name) - { - Assert::isInstanceOf($this->server, Server::class); - - $response = $this->getHttpClient() - ->withUrlParameters([ - 'node' => $this->node->cluster, - 'server' => $this->server->vmid, - 'snapshot' => $name, - ]) - ->delete('/api2/json/nodes/{node}/qemu/{server}/snapshot/{snapshot}') - ->json(); - - return $this->getData($response); - } -} diff --git a/app/Repositories/Repository.php b/app/Repositories/Repository.php deleted file mode 100644 index 3924b3a4252..00000000000 --- a/app/Repositories/Repository.php +++ /dev/null @@ -1,119 +0,0 @@ -app = $application; - - $this->initializeModel($this->model()); - } - - /** - * Return the model backing this repository. - * - * @return string|Closure|object - */ - abstract public function model(); - - /** - * Return the model being used for this repository. - */ - public function getModel(): Model - { - return $this->model; - } - - /** - * Setup column selection functionality. - * - * @param array|string $columns - * @return $this - */ - public function setColumns($columns = ['*']): Repository|static - { - $clone = clone $this; - $clone->columns = is_array($columns) ? $columns : func_get_args(); - - return $clone; - } - - /** - * Return the columns to be selected in the repository call. - */ - public function getColumns(): array - { - return $this->columns; - } - - /** - * Stop repository update functions from returning a fresh - * model when changes are committed. - * - * @return $this - */ - public function withoutFreshModel(): Repository|static - { - return $this->setFreshModel(false); - } - - /** - * Return a fresh model with a repository updates a model. - * - * @return $this - */ - public function withFreshModel() - { - return $this->setFreshModel(true); - } - - /** - * Set whether or not the repository should return a fresh model - * when changes are committed. - * - * @return $this - */ - public function setFreshModel(bool $fresh = true) - { - $clone = clone $this; - $clone->withFresh = $fresh; - - return $clone; - } - - /** - * Take the provided model and make it accessible to the rest of the repository. - * - * @param array $model - */ - protected function initializeModel(...$model): mixed - { - switch (count($model)) { - case 1: - return $this->model = $this->app->make($model[0]); - case 2: - return $this->model = call_user_func([$this->app->make($model[0]), $model[1]]); - default: - throw new InvalidArgumentException('Model must be a FQDN or an array with a count of two.'); - } - } -} diff --git a/app/Rules/Fqdn.php b/app/Rules/Fqdn.php index f8fd41520b4..53f87ac4537 100644 --- a/app/Rules/Fqdn.php +++ b/app/Rules/Fqdn.php @@ -23,14 +23,14 @@ SOFTWARE. */ -namespace Convoy\Rules; +namespace App\Rules; use Closure; -use Illuminate\Support\Arr; use Illuminate\Contracts\Validation\DataAwareRule; use Illuminate\Contracts\Validation\ValidationRule; +use Illuminate\Support\Arr; -class Fqdn implements ValidationRule, DataAwareRule +class Fqdn implements DataAwareRule, ValidationRule { protected array $data = []; @@ -80,9 +80,9 @@ public function validate(string $attribute, $value, Closure $fail): void /** * Returns a new instance of the rule with a defined scheme set. */ - public static function make(string $schemeField = null): self + public static function make(?string $schemeField = null): self { - return tap(new static(), function ($fqdn) use ($schemeField) { + return tap(new self, function ($fqdn) use ($schemeField) { $fqdn->schemeField = $schemeField; }); } diff --git a/app/Rules/HasSufficientAddresses.php b/app/Rules/HasSufficientAddresses.php new file mode 100644 index 00000000000..ea5d6fefd4f --- /dev/null +++ b/app/Rules/HasSufficientAddresses.php @@ -0,0 +1,36 @@ +data = $data; + + return $this; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $ipv4Count = (int) ($this->data['limits']['addresses_ipv4_count'] ?? 0); + $ipv6Count = (int) ($this->data['limits']['addresses_ipv6_count'] ?? 0); + + if ($ipv4Count === 0 && $ipv6Count === 0) { + return; + } + + if (! $this->service->hasSufficientAddresses($value, $ipv4Count, $ipv6Count)) { + $fail('The selected network interface does not have enough available IP addresses.'); + } + } +} diff --git a/app/Rules/HasSufficientCPU.php b/app/Rules/HasSufficientCPU.php new file mode 100644 index 00000000000..7f9d0c617fc --- /dev/null +++ b/app/Rules/HasSufficientCPU.php @@ -0,0 +1,37 @@ +data = $data; + + return $this; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $nodeId = $this->data['node_id'] ?? null; + if (is_null($nodeId)) { + return; + } + + $node = Node::find($nodeId); + if (! $node) { + return; + } + + if ($value > $node->cpu_count) { + $fail('The node does not have enough CPU cores available.'); + } + } +} diff --git a/app/Rules/HasSufficientDiskSpace.php b/app/Rules/HasSufficientDiskSpace.php new file mode 100644 index 00000000000..de99c78cbef --- /dev/null +++ b/app/Rules/HasSufficientDiskSpace.php @@ -0,0 +1,88 @@ +data = $data; + + return $this; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $nodeId = $this->data['node_id'] ?? null; + if (is_null($nodeId)) { + return; + } + + $node = Node::find($nodeId); + if (! $node) { + return; + } + + // Total requested bytes per storage id: primary + each secondary. + $requestedByStorage = []; + + $primaryStorageId = $this->data['storage_id'] ?? null; + $primarySize = Arr::get($this->data, 'limits.disk'); + if (! is_null($primaryStorageId) && ! is_null($primarySize)) { + $requestedByStorage[(int) $primaryStorageId] = (int) $primarySize; + } + + foreach (Arr::get($this->data, 'limits.disks', []) as $disk) { + $storageId = $disk['storage_id'] ?? null; + $size = $disk['size'] ?? null; + if (is_null($storageId) || is_null($size)) { + continue; + } + $requestedByStorage[(int) $storageId] = ($requestedByStorage[(int) $storageId] ?? 0) + (int) $size; + } + + $liveStorage = app(LiveStorageService::class); + + foreach ($requestedByStorage as $storageId => $requested) { + $storage = Storage::query() + ->whereKey($storageId) + ->whereHas('nodes', fn ($query) => $query->whereKey($node->id)) + ->first(); + if (! $storage instanceof Storage) { + continue; + } + + $freeForConvoy = $liveStorage->freeForConvoy($node, $storage); + if ($freeForConvoy === null) { + // Node offline / storage not reported — fail open. + continue; + } + + if ($requested > $freeForConvoy) { + $fail("The storage \"{$storage->name}\" does not have enough disk space available."); + } + } + } +} diff --git a/app/Rules/HasSufficientMemory.php b/app/Rules/HasSufficientMemory.php new file mode 100644 index 00000000000..49a448033cb --- /dev/null +++ b/app/Rules/HasSufficientMemory.php @@ -0,0 +1,37 @@ +data = $data; + + return $this; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $nodeId = $this->data['node_id'] ?? null; + if (is_null($nodeId)) { + return; + } + + $node = Node::find($nodeId); + if (! $node) { + return; + } + + if ($value > $node->memory + ($node->memory * ($node->memory_overallocate / 100))) { + $fail('The node does not have enough memory available.'); + } + } +} diff --git a/app/Rules/Hostname.php b/app/Rules/Hostname.php index 95eecc879ab..473ed5ce0c3 100644 --- a/app/Rules/Hostname.php +++ b/app/Rules/Hostname.php @@ -1,6 +1,8 @@ data = $data; + + return $this; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $diskLimit = Arr::get($this->data, 'limits.disk'); + + if (is_null($diskLimit)) { + return; + } + + $version = ImageDefinition::where('uuid', $value)->first()?->latestVersion(); + + if (! $version) { + return; + } + + if ($version->minimumDiskSize() > $diskLimit) { + $fail('The selected image requires more storage than allocated to the server.'); + } + } +} diff --git a/app/Rules/ImageIsAvailable.php b/app/Rules/ImageIsAvailable.php new file mode 100644 index 00000000000..b2bb8f185ab --- /dev/null +++ b/app/Rules/ImageIsAvailable.php @@ -0,0 +1,58 @@ +data = $data; + + return $this; + } + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $definition = ImageDefinition::where('uuid', $value)->first(); + + if (! $definition) { + return; + } + + if (is_null($definition->latestVersion())) { + $fail('The selected image has no published version to install.'); + + return; + } + + $nodeId = $this->data['node_id'] ?? null; + + if (is_null($nodeId)) { + return; + } + + $node = Node::find($nodeId); + + if ($node && is_null($node->importStorage())) { + $fail("No storage on {$node->name} accepts disk images. Add `Import` to a storage's content types in Proxmox."); + } + } +} diff --git a/app/Rules/IpAddressOrCidr.php b/app/Rules/IpAddressOrCidr.php new file mode 100644 index 00000000000..b1bfa903047 --- /dev/null +++ b/app/Rules/IpAddressOrCidr.php @@ -0,0 +1,39 @@ +isValid($value)) { + $fail('The :attribute field must be a valid IPv4 or IPv6 address or CIDR range.'); + } + } + + private function isValid(string $value): bool + { + $parts = explode('/', trim($value)); + + if (count($parts) === 1) { + return filter_var($parts[0], FILTER_VALIDATE_IP) !== false; + } + + if (count($parts) !== 2 || filter_var($parts[0], FILTER_VALIDATE_IP) === false) { + return false; + } + + [$address, $prefix] = $parts; + + if ($prefix === '' || ! ctype_digit($prefix)) { + return false; + } + + $maximum = filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false ? 32 : 128; + + return (int) $prefix <= $maximum; + } +} diff --git a/app/Rules/NetworkInterfaceBelongsToNode.php b/app/Rules/NetworkInterfaceBelongsToNode.php new file mode 100644 index 00000000000..108f65ae5f6 --- /dev/null +++ b/app/Rules/NetworkInterfaceBelongsToNode.php @@ -0,0 +1,25 @@ +nodeId)) { + $fail('A node must be selected.'); + + return; + } + + if (! NetworkInterface::where('id', $value)->where('node_id', $this->nodeId)->exists()) { + $fail('The selected network interface does not belong to the specified node.'); + } + } +} diff --git a/app/Rules/Password.php b/app/Rules/Password.php index 85d670d6ea2..f01ef8ae8a7 100644 --- a/app/Rules/Password.php +++ b/app/Rules/Password.php @@ -1,6 +1,6 @@ + */ + public static function rules(): array + { + return [ + 'string', + // `uncompromised()` checks HIBP's k-anonymity range API (only a SHA-1 prefix leaves + // the server) and fails open when it is unreachable, so an air-gapped install stays + // usable. + PasswordRule::min(self::MIN_LENGTH)->uncompromised(), + self::withinByteCeiling(), + ]; + } + + /** + * Reject an over-long passphrase rather than quietly truncating it: bcrypt would accept it + * while only its leading 72 bytes ever authenticated. Measured in bytes, not characters, + * because that is the limit bcrypt actually applies — `max:72` counts characters (mb_strlen) + * and would let a 72-character multibyte passphrase through at ~144 bytes. The ceiling still + * clears the 64 characters NIST asks verifiers to accept. + */ + public static function withinByteCeiling(): Closure + { + return function (string $attribute, mixed $value, Closure $fail) { + if (is_string($value) && strlen($value) > self::MAX_BYTES) { + $fail(__('Passwords may be at most :bytes bytes long.', ['bytes' => self::MAX_BYTES])); + } + }; + } +} diff --git a/app/Rules/SshPublicKey.php b/app/Rules/SshPublicKey.php new file mode 100644 index 00000000000..b42aa7c72cb --- /dev/null +++ b/app/Rules/SshPublicKey.php @@ -0,0 +1,75 @@ + [comment]`). Beyond a prefix check, + * it base64-decodes the blob and asserts the length-prefixed algorithm name embedded in it matches + * the declared algorithm — the same integrity check OpenSSH itself performs — so a truncated or + * hand-mangled key is rejected rather than pushed to a VM's cloud-init. + */ +class SshPublicKey implements ValidationRule +{ + private const ALGORITHMS = [ + 'ssh-rsa', + 'ssh-ed25519', + 'ssh-dss', + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521', + 'sk-ssh-ed25519@openssh.com', + 'sk-ecdsa-sha2-nistp256@openssh.com', + ]; + + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $invalid = fn () => $fail('The :attribute is not a valid SSH public key.'); + + if (! is_string($value)) { + $invalid(); + + return; + } + + $parts = preg_split('/\s+/', trim($value)) ?: []; + + if (count($parts) < 2) { + $invalid(); + + return; + } + + [$algorithm, $encoded] = $parts; + + if (! in_array($algorithm, self::ALGORITHMS, true)) { + $invalid(); + + return; + } + + $decoded = base64_decode($encoded, true); + + if ($decoded === false || strlen($decoded) < 4) { + $invalid(); + + return; + } + + // The blob begins with a 4-byte big-endian length followed by the algorithm name; it must + // echo the declared algorithm. + $length = unpack('N', substr($decoded, 0, 4))[1]; + + if ($length <= 0 || strlen($decoded) < 4 + $length) { + $invalid(); + + return; + } + + if (substr($decoded, 4, $length) !== $algorithm) { + $invalid(); + } + } +} diff --git a/app/Rules/StorageAllows.php b/app/Rules/StorageAllows.php new file mode 100644 index 00000000000..cb07e4afaf9 --- /dev/null +++ b/app/Rules/StorageAllows.php @@ -0,0 +1,68 @@ +requiredContentTypes = $contentTypes; + } + + /** + * Run the validation rule. + * + * Checks if the Storage model corresponding to the given ID ($value) + * is configured to store all the specified content types (set to true). + * + * @param string $attribute The name of the attribute being validated. + * @param mixed $value The value of the attribute (the storage ID). + * @param Closure(string): PotentiallyTranslatedString $fail The callback to call if validation fails. + */ + public function validate(string $attribute, mixed $value, Closure $fail): void + { + $storage = Storage::find($value); + + if (! $storage) { + $fail("The selected storage for {$attribute} is invalid."); + + return; + } + + foreach ($this->requiredContentTypes as $contentTypeEnum) { + // Get the corresponding model attribute name (e.g., 'stores_kvm') from the Enum. + $attributeName = $contentTypeEnum->toModelAttributeName(); + + // Check if the corresponding attribute exists on the model and if it's false. + if (! isset($storage->{$attributeName}) || ! $storage->{$attributeName}) { + // Generate a user-friendly name using the Enum case name (e.g., 'KVM'). + $friendlyContentTypeName = Str::headline($contentTypeEnum->name); + + $fail("The storage selected for {$attribute} cannot store: {$friendlyContentTypeName}."); + + return; // No need to check further content types for this storage ID + } + } + } +} diff --git a/app/Rules/USKeyboardCharacters.php b/app/Rules/USKeyboardCharacters.php index 603797658cf..2f160d6aa2e 100644 --- a/app/Rules/USKeyboardCharacters.php +++ b/app/Rules/USKeyboardCharacters.php @@ -1,6 +1,6 @@ whereHas('nodes', function (Builder $query) { + $query->where('nodes.id', $this->nodeId); + }) + ->when($this->ignoreStorageId, function (Builder $query) { + $query->where('id', '!=', $this->ignoreStorageId); + }) + ->exists()) { + $fail('The storage name must be unique within the node.'); + } + } +} diff --git a/app/Rules/VMIDIsAvailable.php b/app/Rules/VMIDIsAvailable.php new file mode 100644 index 00000000000..8b345b5325f --- /dev/null +++ b/app/Rules/VMIDIsAvailable.php @@ -0,0 +1,37 @@ +nodeId)) { + return; + } + + if (Server::where('vmid', $value)->where('node_id', $this->nodeId)->exists()) { + $fail('The specified VMID is already in use on this node.'); + + return; + } + + $node = Node::find($this->nodeId); + if (! $node) { + return; + } + + $client = app(ProxmoxAllocationClient::class)->setNode($node); + if (! $client->isVMIDAvailable((int) $value)) { + $fail('The specified VMID is not available for use on Proxmox.'); + } + } +} diff --git a/app/Rules/ValidHardwareProfile.php b/app/Rules/ValidHardwareProfile.php new file mode 100644 index 00000000000..9b202ac89de --- /dev/null +++ b/app/Rules/ValidHardwareProfile.php @@ -0,0 +1,113 @@ +forNode($this->node); + + foreach ($value as $key => $setting) { + if (in_array($key, OsProfiles::META_KEYS, true)) { + $this->checkSlot($key, $setting, $fail); + + continue; + } + + if (in_array($key, self::COMPUTED_KEYS, true) || preg_match(self::COMPUTED_PATTERN, (string) $key)) { + $fail("The panel sets `{$key}` itself when the server is built; it cannot be part of the profile."); + + continue; + } + + if (! array_key_exists($key, $schema)) { + $fail("Proxmox does not accept a `{$key}` setting when creating a guest."); + + continue; + } + + $this->checkAgainstSchema($key, $setting, $schema[$key], $fail); + } + } + + /** + * The meta keys name a slot rather than carrying a Proxmox value, because + * the storage half of the argument is not known until build time. + */ + private function checkSlot(string $key, mixed $value, Closure $fail): void + { + if (! is_string($value) || ! preg_match('/^(?:scsi|ide|sata|virtio)\d+$/', $value)) { + $fail("`{$key}` must name a disk slot, such as `scsi0` or `ide2`."); + } + } + + /** + * @param array $definition + */ + private function checkAgainstSchema(string $key, mixed $value, array $definition, Closure $fail): void + { + $enum = $definition['enum'] ?? null; + + if (is_array($enum) && ! in_array((string) $value, array_map('strval', $enum), true)) { + $fail("`{$key}` must be one of: ".implode(', ', $enum).'.'); + + return; + } + + // Proxmox's booleans arrive as 0/1 as often as true/false, and its + // integers as numeric strings, so this checks what the value *means* + // rather than what PHP happens to have decoded it as. + match ($definition['type'] ?? 'string') { + 'boolean' => in_array($value, [true, false, 0, 1, '0', '1'], true) + || $fail("`{$key}` must be true or false."), + 'integer', 'number' => is_numeric($value) + || $fail("`{$key}` must be a number."), + default => is_scalar($value) + || $fail("`{$key}` must be a single value, not a list."), + }; + } +} diff --git a/app/Rules/VlanIsDeclaredOnInterface.php b/app/Rules/VlanIsDeclaredOnInterface.php new file mode 100644 index 00000000000..2ce14ed9ad9 --- /dev/null +++ b/app/Rules/VlanIsDeclaredOnInterface.php @@ -0,0 +1,52 @@ +networkInterfaceId + ? NetworkInterface::find($this->networkInterfaceId) + : null; + + if (! $interface) { + $fail('A network interface must be selected before assigning a VLAN.'); + + return; + } + + if (! $interface->is_vlan_aware) { + $fail('The selected network interface must be VLAN-aware before assigning a VLAN tag.'); + + return; + } + + $declared = Vlan::query() + ->where('network_interface_id', $interface->id) + ->where('tag', $value) + ->exists(); + + if (! $declared) { + $fail("VLAN {$value} has not been declared on {$interface->name}. Declare it on the node's Network page first."); + } + } +} diff --git a/app/Services/Activity/ActivityLogBatchService.php b/app/Services/Activity/ActivityLogBatchService.php deleted file mode 100644 index 80e5e25b928..00000000000 --- a/app/Services/Activity/ActivityLogBatchService.php +++ /dev/null @@ -1,63 +0,0 @@ -uuid; - } - - /** - * Starts a new batch transaction. If there is already a transaction present - * this will be nested. - */ - public function start(?string $uuid = null): void - { - if ($this->transaction === 0) { - $this->uuid = $uuid ?? Uuid::uuid4()->toString(); - } - - $this->transaction++; - } - - /** - * Ends a batch transaction, if this is the last transaction in the stack - * the UUID will be cleared out. - */ - public function end(): void - { - $this->transaction = max(0, $this->transaction - 1); - - if ($this->transaction === 0) { - $this->uuid = null; - } - } - - /** - * Executes the logic provided within the callback in the scope of an activity - * log batch transaction. - * - * @return mixed - */ - public function transaction(Closure $callback, ?string $uuid = null) - { - $this->start($uuid); - $result = $callback($this->uuid()); - $this->end(); - - return $result; - } -} diff --git a/app/Services/Activity/ActivityLogService.php b/app/Services/Activity/ActivityLogService.php deleted file mode 100644 index 8c01ace0081..00000000000 --- a/app/Services/Activity/ActivityLogService.php +++ /dev/null @@ -1,261 +0,0 @@ -batch = $batch; - $this->targetable = $targetable; - } - - /** - * Sets the activity logger as having been caused by an anonymous - * user type. - */ - public function anonymous(): self - { - $this->getActivity()->actor_id = null; - $this->getActivity()->actor_type = null; - $this->getActivity()->setRelation('actor', null); - - return $this; - } - - /** - * Sets the action for this activity log. - */ - public function event(string $action): self - { - $this->getActivity()->event = $action; - - return $this; - } - - /** - * Set the description for this activity. - */ - public function description(?string $description): self - { - $this->getActivity()->description = $description; - - return $this; - } - - /** - * Sets the subject model instance. - * - * @param Model|Model[] $subjects - */ - public function subject(...$subjects): self - { - foreach (Arr::wrap($subjects) as $subject) { - foreach ($this->subjects as $entry) { - // If this subject is already tracked in our array of subjects just skip over - // it and move on to the next one in the list. - if ($entry->is($subject)) { - continue 2; - } - } - - $this->subjects[] = $subject; - } - - return $this; - } - - /** - * Sets the actor model instance. - */ - public function actor(Model $actor): self - { - $this->getActivity()->actor()->associate($actor); - - return $this; - } - - /** - * Sets a custom property on the activty log instance. - * - * @param string|array $key - * @param mixed $value - */ - public function property($key, $value = null): self - { - $properties = $this->getActivity()->properties; - $this->activity->properties = is_array($key) - ? $properties->merge($key) - : $properties->put($key, $value); - - return $this; - } - - /** - * Attachs the instance request metadata to the activity log event. - */ - public function withRequestMetadata(): self - { - return $this->property([ - 'ip' => Request::getClientIp(), - 'useragent' => Request::userAgent(), - ]); - } - - /** - * Logs an activity log entry with the set values and then returns the - * model instance to the caller. If there is an exception encountered while - * performing this action it will be logged to the disk but will not interrupt - * the code flow. - */ - public function log(string $description = null): ActivityLog - { - $activity = $this->getActivity(); - - if (! is_null($description)) { - $activity->description = $description; - } - - try { - return $this->save(); - } catch (Throwable|Exception $exception) { - if (config('app.env') !== 'production') { - /* @noinspection PhpUnhandledExceptionInspection */ - throw $exception; - } - - Log::error($exception); - } - - return $activity; - } - - /** - * Returns a cloned instance of the service allowing for the creation of a base - * activity log with the ability to change values on the fly without impact. - */ - public function clone(): self - { - return clone $this; - } - - /** - * Executes the provided callback within the scope of a database transaction - * and will only save the activity log entry if everything else succesfully - * settles. - * - * @return mixed - * - * @throws Throwable - */ - public function transaction(Closure $callback) - { - return $this->connection->transaction(function () use ($callback) { - $response = $callback($this); - - $this->save(); - - return $response; - }); - } - - /** - * Resets the instance and clears out the log. - */ - public function reset(): void - { - $this->activity = null; - $this->subjects = []; - } - - /** - * Returns the current activity log instance. - */ - protected function getActivity(): ActivityLog - { - if ($this->activity) { - return $this->activity; - } - - $this->activity = new ActivityLog([ - - 'ip' => Request::ip(), - 'batch' => $this->batch->uuid(), - 'properties' => Collection::make([]), - 'api_key_id' => $this->targetable->apiKeyId(), - ]); - - if ($subject = $this->targetable->subject()) { - $this->subject($subject); - } - - if ($actor = $this->targetable->actor()) { - $this->actor($actor); - } elseif ($user = $this->manager->guard()->user()) { - if ($user instanceof Model) { - $this->actor($user); - } - } - - return $this->activity; - } - - /** - * Saves the activity log instance and attaches all of the subject models. - * - * @throws Throwable - */ - protected function save(): ActivityLog - { - Assert::notNull($this->activity); - - $response = $this->connection->transaction(function () { - $this->activity->save(); - - $subjects = Collection::make($this->subjects) - ->map(fn (Model $subject) => [ - 'activity_log_id' => $this->activity->id, - 'subject_id' => $subject->getKey(), - 'subject_type' => $subject->getMorphClass(), - ]) - ->values() - ->toArray(); - - ActivityLogSubject::insert($subjects); - - return $this->activity; - }); - - $this->activity = null; - $this->subjects = []; - - return $response; - } -} diff --git a/app/Services/Activity/ActivityLogTargetableService.php b/app/Services/Activity/ActivityLogTargetableService.php deleted file mode 100644 index 195e6660fb9..00000000000 --- a/app/Services/Activity/ActivityLogTargetableService.php +++ /dev/null @@ -1,51 +0,0 @@ -actor = $actor; - } - - public function setSubject(Model $subject): void - { - $this->subject = $subject; - } - - public function setApiKeyId(?int $apiKeyId): void - { - $this->apiKeyId = $apiKeyId; - } - - public function actor(): ?Model - { - return $this->actor; - } - - public function subject(): ?Model - { - return $this->subject; - } - - public function apiKeyId(): ?int - { - return $this->apiKeyId; - } - - public function reset(): void - { - $this->actor = null; - $this->subject = null; - $this->apiKeyId = null; - } -} diff --git a/app/Services/Activity/BulkAddressCreationService.php b/app/Services/Activity/BulkAddressCreationService.php deleted file mode 100644 index 9acb1d71eed..00000000000 --- a/app/Services/Activity/BulkAddressCreationService.php +++ /dev/null @@ -1,62 +0,0 @@ -whereIn('address', $addresses) - ->get('address') - ->pluck('address') - ->toArray(); - $addresses = array_diff($addresses, $existingAddresses); - - $transformer = function (string $address) use ( - $poolId, $serverId, $type, $cidr, $gateway, $macAddress, - ) { - return [ - 'address_pool_id' => $poolId, - 'server_id' => $serverId, - 'type' => $type->value, - 'address' => $address, - 'cidr' => $cidr, - 'gateway' => $gateway, - 'mac_address' => $macAddress, - ]; - }; - - /** - * @var array{ - * address_pool_id: int, - * server_id: ?int, - * type: string, - * address: string, - * cidr: int, - * gateway: string, - * mac_address: ?string, - * } $addresses - */ - $addresses = Arr::map( - $addresses, $transformer, - ); - - Address::insert($addresses); - } -} \ No newline at end of file diff --git a/app/Services/Addresses/AddressAllocationService.php b/app/Services/Addresses/AddressAllocationService.php new file mode 100644 index 00000000000..03a0bea7a77 --- /dev/null +++ b/app/Services/Addresses/AddressAllocationService.php @@ -0,0 +1,201 @@ +getSize(); ...)` + * keyed off `prefix_length_from`, effectively unbounded for IPv6 — that also raced. + * + * MUST run inside a database transaction: the reclaim row locks and the sparse per-block lock + * hold the reservation only until the surrounding transaction commits, which is where the + * caller stamps `server_id` via ServerNetworkService::syncAddresses(). ServerCreationService, + * the sole caller, wraps the whole create in `DB::transaction()`. + * + * @return Collection + * + * @throws InsufficientAddressesException + */ + public function handle(int $networkInterfaceId, int $requestedIpv4, int $requestedIpv6): Collection + { + $networkInterface = NetworkInterface::with('addressBlockGroups.addressBlocks') + ->findOrFail($networkInterfaceId); + + /** @var Collection> $blocksByVersion */ + $blocksByVersion = $networkInterface->addressBlockGroups + ->flatMap(fn ($group) => $group->addressBlocks) + ->groupBy(fn (AddressBlock $block) => $block->version->value); + + return $this->allocateForVersion($blocksByVersion, AddressVersion::IPv4, $requestedIpv4) + ->merge($this->allocateForVersion($blocksByVersion, AddressVersion::IPv6, $requestedIpv6)) + ->values(); + } + + /** + * @param Collection> $blocksByVersion + * @return Collection + * + * @throws InsufficientAddressesException + */ + private function allocateForVersion(Collection $blocksByVersion, AddressVersion $version, int $count): Collection + { + if ($count <= 0) { + return new Collection; + } + + /** @var Collection $blocks */ + $blocks = $blocksByVersion->get($version->value) ?? new Collection; + + if ($blocks->isEmpty()) { + throw new InsufficientAddressesException; + } + + // 1. Reclaim existing available rows across every block of this version. Reserved rows + // (network/broadcast/gateway or held-out IPs) are excluded — that's the auto-exclusion. + $result = Address::query() + ->with('addressBlock') + ->whereIn('address_block_id', $blocks->pluck('id')->all()) + ->where('state', AddressState::Available) + // ip is an inet column, so this orders numerically and is served without a sort by the + // partial index addresses_available_by_block_ip_idx. + ->orderBy('ip') + ->limit($count) + // FOR UPDATE SKIP LOCKED (Postgres + MySQL 8.0). Laravel has no skip-locked helper. + ->lock('FOR UPDATE SKIP LOCKED') + ->get(); + + $needed = $count - $result->count(); + + // 2. Mint the shortfall from sparse blocks (nothing to mint for dense blocks — their free + // rows were already all materialized and thus covered by the reclaim query above). + foreach ($blocks->filter->isSparse() as $block) { + if ($needed <= 0) { + break; + } + + $minted = $this->mintFromSparseBlock($block, $needed); + $result = $result->merge($minted); + $needed -= $minted->count(); + } + + if ($needed > 0) { + throw new InsufficientAddressesException; + } + + return $result; + } + + /** + * Mint up to $count fresh addresses at the top of a sparse block, appending after the highest + * address already stored (`MAX(ip)`, served O(log N) by the unique (address_block_id, ip) + * index). No offset walk and no pre-materialization: a v6 /64 hands out its first N addresses + * in N index lookups, never 2^64 rows. + * + * The block row is locked `FOR UPDATE` first so concurrent allocations against the *same* sparse + * block serialize their cursor advance — the next candidate is always `MAX(ip) + stride`, which + * by definition can't already exist, so no unique conflict and no double-assign. (Freed rows + * below the cursor re-enter via the reclaim query above, not here.) + * + * @return Collection + */ + private function mintFromSparseBlock(AddressBlock $block, int $count): Collection + { + // Serialize cursor advancement for this block (held until the outer transaction commits). + DB::table('address_blocks')->where('id', $block->id)->lockForUpdate()->first(); + + // Materialize the low system-reserved units (network / the gateway's unit) as reserved rows + // so minting — which appends after MAX(ip) — starts above them and never hands them out. The + // broadcast (block ceiling) is intentionally not materialized: it sits at the very top, so a + // reserved row there would make MAX(ip) the ceiling and stall minting. At sparse-block scale + // (2^16+ addresses) minting never climbs near the broadcast anyway. + // + // Caveat, unchanged from when this only handled the raw gateway: a gateway high up in a + // sparse block pushes MAX(ip) up with it, so the units below it are skipped rather than + // minted. Gateways sit at the bottom of a prefix in practice (.1, ::1). + $this->reserveLowSystemAddresses($block); + + $stride = $block->unitStride(); + $lastAddress = $block->lastAllocatableAddress(); + $mintedIds = []; + + for ($i = 0; $i < $count; $i++) { + // Compute the next candidate (MAX(ip)+stride, or base_ip for an empty block), range-check + // it against the block ceiling, and insert it — all in one statement so the cursor read + // and the insert can't interleave. ON CONFLICT is a defensive no-op (see method doc). + $row = DB::selectOne( + <<<'SQL' + WITH cand AS ( + SELECT COALESCE( + (SELECT MAX(ip) FROM addresses WHERE address_block_id = ?) + ?::bigint, + ?::inet + ) AS ip + ), + chk AS (SELECT ip, ip <= ?::inet AS ok FROM cand), + ins AS ( + INSERT INTO addresses (address_block_id, ip, prefix_length, server_id, state) + SELECT ?, ip, ?, NULL, ? FROM chk WHERE ok + ON CONFLICT (address_block_id, ip) DO NOTHING + RETURNING id + ) + SELECT (SELECT ok FROM chk) AS ok, (SELECT id FROM ins) AS inserted_id + SQL, + [$block->id, $stride, $block->base_ip, $lastAddress, $block->id, $block->prefix_length_to, AddressState::Available->value], + ); + + // !ok = block exhausted; inserted_id null with ok = unexpected conflict — stop either way. + if (! $row->ok || $row->inserted_id === null) { + break; + } + + $mintedIds[] = $row->inserted_id; + } + + return Address::with('addressBlock')->findMany($mintedIds); + } + + /** + * Ensure the block's network and gateway addresses exist as reserved rows (idempotent). These + * are the "low" system-reserved addresses; the broadcast is deliberately excluded (see caller). + */ + private function reserveLowSystemAddresses(AddressBlock $block): void + { + $broadcast = $block->version === AddressVersion::IPv4 && $block->prefix_length_from <= 30 + ? $block->lastAllocatableAddress() + : null; + + foreach ($block->systemReservedAddresses() as $ip) { + if ($ip === $broadcast) { + continue; + } + + DB::insert( + 'INSERT INTO addresses (address_block_id, ip, prefix_length, server_id, state, state_reason) + VALUES (?, ?::inet, ?, NULL, ?, ?) ON CONFLICT (address_block_id, ip) DO NOTHING', + [$block->id, $ip, $block->prefix_length_to, AddressState::Reserved->value, AddressStateReason::System->value], + ); + } + } +} diff --git a/app/Services/Addresses/AddressAvailabilityService.php b/app/Services/Addresses/AddressAvailabilityService.php new file mode 100644 index 00000000000..31bb26cb4e5 --- /dev/null +++ b/app/Services/Addresses/AddressAvailabilityService.php @@ -0,0 +1,44 @@ + fn ($query) => $query->withCount(['addresses' => fn ($q) => $q->whereNotNull('server_id')]), + ])->findOrFail($networkInterfaceId); + + $availableIpv4 = gmp_init(0); + $availableIpv6 = gmp_init(0); + + foreach ($networkInterface->addressBlockGroups as $group) { + foreach ($group->addressBlocks as $block) { + $isV4 = $block->version === AddressVersion::IPv4; + $totalAddressSpace = gmp_pow(2, ($isV4 ? 32 : 128) - $block->prefix_length_from); + + $allocatedCount = gmp_init($block->addresses_count); + $sizeOfSingleAllocation = gmp_pow(2, ($isV4 ? 32 : 128) - $block->prefix_length_to); + $allocatedAddressSpace = gmp_mul($allocatedCount, $sizeOfSingleAllocation); + + $available = gmp_sub($totalAddressSpace, $allocatedAddressSpace); + + if ($isV4) { + $availableIpv4 = gmp_add($availableIpv4, $available); + } else { + $availableIpv6 = gmp_add($availableIpv6, $available); + } + + if (gmp_cmp($availableIpv4, $requestedIpv4) >= 0 && gmp_cmp($availableIpv6, $requestedIpv6) >= 0) { + return true; + } + } + } + + return gmp_cmp($availableIpv4, $requestedIpv4) >= 0 && gmp_cmp($availableIpv6, $requestedIpv6) >= 0; + } +} diff --git a/app/Services/Admin/OverviewService.php b/app/Services/Admin/OverviewService.php index b5574ad48d0..e0ed1370925 100644 --- a/app/Services/Admin/OverviewService.php +++ b/app/Services/Admin/OverviewService.php @@ -1,66 +1,173 @@ $this->build(), - ); + /** @var OverviewData $data */ + $data = Cache::remember(self::CACHE_KEY, self::CACHE_SECONDS, fn () => $this->build()); + + // The DataCollection context is not preserved across cache serialization; re-apply the + // endpoint contract so cached responses keep `nodes` as an array instead of `{ data: [] }`. + $data->nodes->withoutWrapping(); + + return $data; } - private function build(): array + /** + * Flattened scalar metrics recorded to the time-series store. Names are prefixed so a single + * range query (`convoy_overview_.+`) fetches them all back for trends. + * + * @return array + */ + public function snapshotMetrics(): array { - $nodes = $this->loadNodes(); - $allocations = $this->loadServerAllocations(); - $statuses = $this->loadServerStatuses(); + $m = $this->metrics(); return [ - 'generated_at' => now(), - 'summary' => $this->summary($nodes, $statuses), - 'servers' => $this->servers($statuses), - 'capacity' => $this->capacity($nodes, $allocations), - 'addresses' => $this->addresses(), - 'backups' => $this->backups(), - 'isos' => $this->isos(), - 'nodes' => $nodes - ->map(fn (Node $node) => $this->node($node, $allocations)) - ->all(), + 'convoy_overview_servers' => $m->summary->servers, + 'convoy_overview_nodes' => $m->summary->nodes, + 'convoy_overview_users' => $m->summary->users, + 'convoy_overview_locations' => $m->summary->locations, + 'convoy_overview_failed_servers' => $m->summary->failedServers, + 'convoy_overview_memory_percent' => $m->memory->percent, + 'convoy_overview_storage_percent' => $m->storage->percent, + 'convoy_overview_addresses_assigned' => $m->addresses->assigned, + 'convoy_overview_backups_total' => $m->backups->total, + 'convoy_overview_backups_failed' => $m->backups->failed, + 'convoy_overview_isos_total' => $m->isos->total, ]; } + private function build(): OverviewData + { + $nodes = $this->loadNodes(); + $allocations = $this->loadServerAllocations(); + $lifecycles = $this->loadServerLifecycles(); + $suspended = $this->countSuspendedServers(); + + return new OverviewData( + generatedAt: CarbonImmutable::now(), + summary: $this->summary($nodes, $lifecycles), + servers: $this->servers($lifecycles, $suspended), + memory: $this->memory($nodes, $allocations), + storage: $this->storage($allocations), + addresses: $this->addresses(), + backups: $this->backups(), + isos: $this->isos(), + nodes: NodeSummaryData::collect( + $nodes->map(fn (Node $node) => $this->node($node, $allocations))->values(), + DataCollection::class, + )->withoutWrapping(), + trends: $this->trends(), + ); + } + + private function trends(): OverviewTrendsData + { + // One range query over ~30 days (daily step) powers both the sparkline series and the delta. + $series = $this->metrics->queryRange('{__name__=~"convoy_overview_.+"}', '-30d', 'now', '86400'); + + return new OverviewTrendsData( + servers: $this->trend($series, 'convoy_overview_servers'), + nodes: $this->trend($series, 'convoy_overview_nodes'), + users: $this->trend($series, 'convoy_overview_users'), + backups: $this->trend($series, 'convoy_overview_backups_total'), + ); + } + + /** @param array> $series */ + private function trend(array $series, string $name): MetricTrendData + { + $points = $series[$name] ?? []; + if ($points === []) { + return new MetricTrendData(delta: null, series: []); + } + + $values = array_map(fn (array $point): float => $point[1], $points); + $current = end($values); + + // Delta vs. the sample nearest 7 days ago — but only once we hold ~a week of history, so a + // fresh install shows no misleading delta. + $delta = null; + if ($points[0][0] <= now()->subDays(6)->getTimestamp()) { + $target = now()->subDays(7)->getTimestamp(); + $nearest = $points[0][1]; + $bestDiff = PHP_INT_MAX; + foreach ($points as [$timestamp, $value]) { + $diff = abs($timestamp - $target); + if ($diff < $bestDiff) { + $bestDiff = $diff; + $nearest = $value; + } + } + $delta = round($current - $nearest, 2); + } + + return new MetricTrendData(delta: $delta, series: array_values($values)); + } + + /** @return Collection */ private function loadNodes(): Collection { return Node::query() - ->select(['id', 'name', 'cluster', 'fqdn', 'memory', 'disk']) + ->select(['id', 'display_name', 'name', 'fqdn', 'memory', 'status', 'status_checked_at']) ->withCount('servers') - ->orderBy('name') + ->orderBy('display_name') ->get(); } + /** + * Per-node committed memory/disk. These are raw aggregates over the (MiB) DB columns — + * StorageSizeCast is not applied to the SUM alias — so callers convert to bytes. + * + * @return Collection keyed by node_id + */ private function loadServerAllocations(): Collection { return Server::query() + ->toBase() ->select('node_id') ->selectRaw('COALESCE(SUM(memory), 0) as memory_allocated') ->selectRaw('COALESCE(SUM(disk), 0) as disk_allocated') @@ -69,151 +176,164 @@ private function loadServerAllocations(): Collection ->keyBy('node_id'); } - private function loadServerStatuses(): Collection + /** @return Collection lifecycle value => count */ + private function loadServerLifecycles(): Collection { return Server::query() - ->select('status') + ->toBase() + ->select('lifecycle') ->selectRaw('COUNT(*) as total') - ->groupBy('status') + ->groupBy('lifecycle') ->get() - ->mapWithKeys(fn (Server $row) => [ - $row->status ?? 'ready' => (int) $row->total, - ]); + ->mapWithKeys(fn (object $row) => [(string) $row->lifecycle => (int) $row->total]); } - private function summary(Collection $nodes, Collection $statuses): array + /** + * Suspended servers, counted separately because suspension is not a lifecycle bucket. + * + * These rows are *also* counted under whatever lifecycle they're in, so this figure + * overlaps the breakdown rather than partitioning it -- it must never be summed with + * the lifecycle counts to get a total. + */ + private function countSuspendedServers(): int { - return [ - 'servers' => (int) $statuses->sum(), - 'nodes' => $nodes->count(), - 'users' => User::query()->count(), - 'locations' => Location::query()->count(), - 'failed_servers' => $this->failedServers($statuses), - ]; + return Server::query()->whereNotNull('suspended_at')->count(); } - private function servers(Collection $statuses): array + /** @param Collection $nodes */ + private function summary(Collection $nodes, Collection $lifecycles): FleetSummaryData { - return [ - 'total' => (int) $statuses->sum(), - 'ready' => (int) ($statuses['ready'] ?? 0), - 'installing' => (int) ($statuses[Status::INSTALLING->value] ?? 0), - 'suspended' => (int) ($statuses[Status::SUSPENDED->value] ?? 0), - 'restoring' => (int) ( - ($statuses[Status::RESTORING_BACKUP->value] ?? 0) - + ($statuses[Status::RESTORING_SNAPSHOT->value] ?? 0) - ), - 'deleting' => (int) ($statuses[Status::DELETING->value] ?? 0), - 'failed' => $this->failedServers($statuses), - 'statuses' => $statuses->all(), - ]; + return new FleetSummaryData( + servers: (int) $lifecycles->sum(), + nodes: $nodes->count(), + users: User::query()->count(), + locations: Location::query()->count(), + failedServers: $this->failedServers($lifecycles), + flaggedClusters: Cluster::query()->whereNotNull('flagged_at')->count(), + ); } - private function failedServers(Collection $statuses): int + private function servers(Collection $lifecycles, int $suspended): ServerBreakdownData { - return (int) ( - ($statuses[Status::INSTALL_FAILED->value] ?? 0) - + ($statuses[Status::DELETION_FAILED->value] ?? 0) + return new ServerBreakdownData( + total: (int) $lifecycles->sum(), + ready: (int) ($lifecycles[ServerLifecycle::READY->value] ?? 0), + installing: (int) ($lifecycles[ServerLifecycle::INSTALLING->value] ?? 0), + restoring: (int) ($lifecycles[ServerLifecycle::RESTORING_BACKUP->value] ?? 0), + deleting: (int) ($lifecycles[ServerLifecycle::DELETING->value] ?? 0), + failed: $this->failedServers($lifecycles), + suspended: $suspended, + flagged: Server::query()->whereNotNull('flagged_at')->count(), + lifecycles: $lifecycles->all(), ); } - private function capacity(Collection $nodes, Collection $allocations): array + private function failedServers(Collection $lifecycles): int { - $memoryAllocated = $allocations->sum( - fn ($row) => $this->mebibytesToBytes((int) $row->memory_allocated), - ); - $diskAllocated = $allocations->sum( - fn ($row) => $this->mebibytesToBytes((int) $row->disk_allocated), + return (int) ( + ($lifecycles[ServerLifecycle::INSTALL_FAILED->value] ?? 0) + + ($lifecycles[ServerLifecycle::DELETION_FAILED->value] ?? 0) ); - - return [ - 'memory' => $this->metric($memoryAllocated, (int) $nodes->sum('memory')), - 'disk' => $this->metric($diskAllocated, (int) $nodes->sum('disk')), - ]; } - private function addresses(): array + /** @param Collection $nodes */ + private function memory(Collection $nodes, Collection $allocations): ResourceAllocationData { - $stats = Address::query() - ->selectRaw('COUNT(*) as total') - ->selectRaw('SUM(server_id IS NOT NULL) as assigned') - ->first(); - - $total = (int) $stats->total; - $assigned = (int) $stats->assigned; + // $node->memory is StorageSizeCast (bytes); the allocation aggregate is raw (MiB). + $allocated = ByteUnit::Mebibytes->toBytes((int) $allocations->sum('memory_allocated')); - return [ - 'pools' => AddressPool::query()->count(), - 'total' => $total, - 'assigned' => $assigned, - 'available' => max($total - $assigned, 0), - 'percent' => $this->percentage($assigned, $total), - ]; + return $this->allocation($allocated, (int) $nodes->sum('memory')); } - private function backups(): array + private function storage(Collection $allocations): ResourceAllocationData { - $stats = Backup::query() - ->selectRaw('COUNT(*) as total') - ->selectRaw('SUM(completed_at IS NOT NULL) as completed') - ->selectRaw('SUM(is_successful = 1) as successful') - ->selectRaw('SUM(completed_at IS NULL) as pending') - ->first(); + $allocated = ByteUnit::Mebibytes->toBytes((int) $allocations->sum('disk_allocated')); - return [ - 'total' => (int) $stats->total, - 'successful' => (int) $stats->successful, - 'pending' => (int) $stats->pending, - 'failed' => max((int) $stats->completed - (int) $stats->successful, 0), - ]; + /* + * Total VM-disk capacity: distinct storages that back VM disks and are + * attached to a node (storage no node reaches is not usable fleet + * capacity). Distinct by row, so a shared pool counts once however many + * nodes mount it. + * + * Prefers what the poll observed over what the operator typed. `size` is + * a hand-entered figure that nothing checks and everything else on the + * storage now reads from discovery; leaving the one fleet-wide number on + * the declared value would make the dashboard disagree with every page + * beneath it. It remains the fallback for a storage no node has reported + * yet, which is the only case where it is the best answer available. + */ + $total = (int) Storage::query() + ->stores(StorageContentType::KVM) + ->whereHas('nodes') + ->with('nodes') + ->get() + ->sum(fn (Storage $storage) => $storage->recordedCapacity()['total'] ?? $storage->size); + + return $this->allocation($allocated, $total); } - private function isos(): array + private function addresses(): AddressUsageData { - $stats = ISO::query() - ->selectRaw('COUNT(*) as total') - ->selectRaw('SUM(is_successful = 1) as successful') - ->first(); + $total = Address::query()->count(); + $assigned = Address::query()->whereNotNull('server_id')->count(); - $total = (int) $stats->total; - $successful = (int) $stats->successful; + return new AddressUsageData( + pools: AddressBlockGroup::query()->count(), + total: $total, + assigned: $assigned, + available: max($total - $assigned, 0), + percent: $this->percentage($assigned, $total), + ); + } - return [ - 'total' => $total, - 'successful' => $successful, - 'pending' => max($total - $successful, 0), - ]; + private function backups(): BackupSummaryData + { + return new BackupSummaryData( + total: Backup::query()->count(), + successful: Backup::query()->successful()->count(), + pending: Backup::query()->whereNull('completed_at')->count(), + failed: Backup::query()->whereNotNull('completed_at')->whereNotNull('error_code')->count(), + ); } - private function node(Node $node, Collection $allocations): array + private function isos(): ISOSummaryData { - $row = $allocations->get($node->id); - $memoryAllocated = $this->mebibytesToBytes((int) ($row->memory_allocated ?? 0)); - $diskAllocated = $this->mebibytesToBytes((int) ($row->disk_allocated ?? 0)); + // A library entry is complete the moment it exists -- there is no + // per-node download to be pending on any more, because residency is + // settled when someone mounts it. + $total = ISO::query()->count(); - return [ - 'id' => $node->id, - 'name' => $node->name, - 'cluster' => $node->cluster, - 'fqdn' => $node->fqdn, - 'servers' => (int) $node->servers_count, - 'memory' => $this->metric($memoryAllocated, (int) $node->memory), - 'disk' => $this->metric($diskAllocated, (int) $node->disk), - ]; + return new ISOSummaryData( + total: $total, + successful: $total, + pending: 0, + ); } - private function metric(int $allocated, int $total): array + private function node(Node $node, Collection $allocations): NodeSummaryData { - return [ - 'allocated' => $allocated, - 'total' => $total, - 'percent' => $this->percentage($allocated, $total), - ]; + $row = $allocations->get($node->id); + $allocated = ByteUnit::Mebibytes->toBytes((int) ($row->memory_allocated ?? 0)); + + return new NodeSummaryData( + id: $node->id, + displayName: $node->display_name, + name: $node->name, + fqdn: $node->fqdn, + servers: (int) $node->servers_count, + status: $node->currentStatus(), + memory: $this->allocation($allocated, (int) $node->memory), + resources: $this->resourceSnapshots->for($node), + ); } - private function mebibytesToBytes(int $value): int + private function allocation(int $allocated, int $total): ResourceAllocationData { - return $value * self::BYTES_PER_MEBIBYTE; + return new ResourceAllocationData( + allocated: $allocated, + total: $total, + percent: $this->percentage($allocated, $total), + ); } private function percentage(int $value, int $total): float diff --git a/app/Services/Admin/UpdateCheckService.php b/app/Services/Admin/UpdateCheckService.php new file mode 100644 index 00000000000..29f3b5ac82f --- /dev/null +++ b/app/Services/Admin/UpdateCheckService.php @@ -0,0 +1,161 @@ +toStatus(Cache::get(self::CACHE_KEY)); + } + + /** + * Fetches the newest published release and caches it. + * + * A failed fetch leaves the previous result in place rather than blanking + * it: a transient GitHub outage should not make an out-of-date panel look + * up to date. + * + * @throws UpdateCheckFailedException when the release cannot be fetched or parsed + */ + public function check(): UpdateStatusData + { + $release = $this->fetchLatestRelease(); + + Cache::put(self::CACHE_KEY, $release, now()->addDays(self::CACHE_DAYS)); + + return $this->toStatus($release); + } + + /** + * @return array{version: string, url: string|null, releasedAt: string|null, checkedAt: string} + * + * @throws UpdateCheckFailedException + */ + private function fetchLatestRelease(): array + { + $repository = config('convoy.updates.repository'); + $url = "https://api.github.com/repos/{$repository}/releases/latest"; + + try { + $response = Http::timeout(self::TIMEOUT_SECONDS) + ->withHeaders([ + 'Accept' => 'application/vnd.github+json', + 'X-GitHub-Api-Version' => '2022-11-28', + // GitHub rejects requests without one, and an identifiable + // agent is the courteous way to consume a public API. + 'User-Agent' => 'Convoy/'.config('app.version'), + ]) + ->get($url); + } catch (Throwable $exception) { + throw new UpdateCheckFailedException( + "Could not reach {$url}: {$exception->getMessage()}", + $exception, + ); + } + + if (! $response->successful()) { + throw new UpdateCheckFailedException("{$url} responded with HTTP {$response->status()}."); + } + + $tag = (string) $response->json('tag_name'); + + if ($tag === '') { + throw new UpdateCheckFailedException("{$url} returned a release without a tag name."); + } + + return [ + 'version' => $this->normalize($tag), + 'url' => $response->json('html_url'), + 'releasedAt' => $response->json('published_at'), + 'checkedAt' => now()->toIso8601String(), + ]; + } + + /** + * @param array{version: string, url: string|null, releasedAt: string|null, checkedAt: string}|null $release + */ + private function toStatus(?array $release): UpdateStatusData + { + $current = (string) config('app.version'); + $latest = $release === null ? null : Arr::get($release, 'version'); + + $comparable = $latest !== null && $current !== self::DEVELOPMENT_VERSION; + $updateAvailable = $comparable + && version_compare($latest, $this->normalize($current), '>'); + + return new UpdateStatusData( + currentVersion: $current, + latestVersion: $latest, + releaseUrl: $release === null ? null : Arr::get($release, 'url'), + releasedAt: $release === null ? null : Arr::get($release, 'releasedAt'), + checkedAt: $release === null ? null : Arr::get($release, 'checkedAt'), + repository: (string) config('convoy.updates.repository'), + updateAvailable: $updateAvailable, + status: match (true) { + ! $comparable => UpdateStatus::UNKNOWN, + $updateAvailable => UpdateStatus::UPDATE_AVAILABLE, + default => UpdateStatus::UP_TO_DATE, + }, + ); + } + + /** + * Tags are cut as `v4.6.1` but the embedded version is written without the + * prefix, so both sides are stripped before `version_compare` sees them. + * It already orders `4.6.1-rc.1` below `4.6.1`, which is what an install + * running a release candidate should be told. + */ + private function normalize(string $version): string + { + return ltrim(trim($version), 'vV'); + } +} diff --git a/app/Services/Anchor/AnchorApprovalService.php b/app/Services/Anchor/AnchorApprovalService.php new file mode 100644 index 00000000000..0330e1dad57 --- /dev/null +++ b/app/Services/Anchor/AnchorApprovalService.php @@ -0,0 +1,108 @@ + $attributes the operator's decisions: location, + * address, credentials, capacity + */ + public function approveNode(AnchorEnrollment $enrollment, array $attributes): Node + { + return DB::transaction(function () use ($enrollment, $attributes) { + $node = Node::create([ + // Defaults for what the approval screen does not ask about. + // TLS verification errs toward on: turning it off is a decision + // about a trusted private path, never an omission. + 'verify_tls' => true, + ...$attributes, + 'agent_uuid' => $enrollment->uuid, + 'agent_secret' => $enrollment->secret, + 'agent_enrollment_key_id' => $enrollment->enrollment_key_id, + 'agent_reported_facts' => $enrollment->reported_facts, + 'agent_enrolled_at' => $enrollment->enrolled_at, + 'agent_last_seen_at' => $enrollment->last_seen_at, + 'agent_version' => $enrollment->version, + 'agent_protocol_min' => $enrollment->protocol_min, + 'agent_protocol_max' => $enrollment->protocol_max, + 'agent_capabilities' => $enrollment->capabilities, + ]); + + $enrollment->delete(); + + return $node; + }); + } + + /** @param array $attributes */ + public function approveRelay(AnchorEnrollment $enrollment, array $attributes): Relay + { + return DB::transaction(function () use ($enrollment, $attributes) { + $relay = Relay::create([ + ...Arr::only($attributes, ['name', 'public_url', 'panel_url_override']), + 'uuid' => $enrollment->uuid, + 'secret' => $enrollment->secret, + 'enrollment_key_id' => $enrollment->enrollment_key_id, + 'reported_facts' => $enrollment->reported_facts, + 'enrolled_at' => $enrollment->enrolled_at, + 'last_seen_at' => $enrollment->last_seen_at, + 'version' => $enrollment->version, + 'protocol_min' => $enrollment->protocol_min, + 'protocol_max' => $enrollment->protocol_max, + 'capabilities' => $enrollment->capabilities, + ]); + + $enrollment->delete(); + + return $relay; + }); + } + + /** + * The node fields the machine already answered, for pre-filling the + * approval screen. + * + * Capacity comes back as facts the host reported about itself, not as + * policy: `memory_overallocate` is absent on purpose, because how far to + * oversubscribe is a decision and the host has no view on it. + * + * @return array + */ + public function suggestions(AnchorEnrollment $enrollment): array + { + $facts = $enrollment->reported_facts ?? []; + $cpu = Arr::get($facts, 'cpu', []); + + return array_filter([ + 'display_name' => Arr::get($facts, 'hostname') ?: $enrollment->name, + 'name' => Arr::get($facts, 'pve_node_name'), + // The hostname the machine gave, else the address the request + // actually came from -- the one reachability claim it cannot + // overstate. Both are candidates for a human to confirm. + 'fqdn' => Arr::get($facts, 'hostname') ?: Arr::get($facts, 'observed_source_ip'), + 'socket_count' => Arr::get($cpu, 'sockets'), + 'core_count' => Arr::get($cpu, 'cores'), + 'cpu_count' => Arr::get($cpu, 'threads'), + 'memory' => Arr::get($facts, 'memory_bytes'), + ], fn ($value) => $value !== null && $value !== ''); + } +} diff --git a/app/Services/Anchor/AnchorEnrollmentKeyService.php b/app/Services/Anchor/AnchorEnrollmentKeyService.php new file mode 100644 index 00000000000..64f532ceb86 --- /dev/null +++ b/app/Services/Anchor/AnchorEnrollmentKeyService.php @@ -0,0 +1,60 @@ + (string) Str::uuid(), + 'name' => $name, + 'token_hash' => hash('sha256', $token), + 'mode' => $mode, + 'max_uses' => $maxUses, + 'uses' => 0, + 'expires_at' => $expiresInMinutes === null + ? null + : now()->addMinutes($expiresInMinutes), + 'created_by' => $actor?->id, + ]); + + return new IssuedEnrollmentKey($key->loadMissing('createdBy'), $token); + } +} diff --git a/app/Services/Anchor/AnchorEnrollmentService.php b/app/Services/Anchor/AnchorEnrollmentService.php new file mode 100644 index 00000000000..204c7538002 --- /dev/null +++ b/app/Services/Anchor/AnchorEnrollmentService.php @@ -0,0 +1,50 @@ +addMinutes(15); + + // A node's agent columns are prefixed to keep them apart from its + // Proxmox liveness; a relay is nothing but an installation, so its are + // not. One place pays for that, rather than every caller. + $prefix = $installation instanceof Node ? 'agent_' : ''; + + $installation->update([ + $prefix.'enrollment_token_hash' => hash('sha256', $token), + $prefix.'enrollment_expires_at' => $expiresAt, + ]); + + // The same URL the enrollment response will write into the agent's + // config, so the command shown here cannot disagree with what the + // agent ends up using. + $command = sprintf( + "anchor enroll --panel-url %s --token '%s'", + $installation->anchorPanelUrl(), + $token, + ); + + return new AnchorEnrollmentData( + token: $token, + command: $command, + expiresAt: $expiresAt->toIso8601String(), + ); + } +} diff --git a/app/Services/Anchor/AnchorIdentityService.php b/app/Services/Anchor/AnchorIdentityService.php new file mode 100644 index 00000000000..83ce263f325 --- /dev/null +++ b/app/Services/Anchor/AnchorIdentityService.php @@ -0,0 +1,47 @@ +where('agent_uuid', $uuid)->first() + ?? Relay::query()->where('uuid', $uuid)->first() + ?? AnchorEnrollment::query()->where('uuid', $uuid)->first(); + + if ($installation === null) { + return null; + } + + $known = $installation->anchorSecret(); + + // hash_equals over a plain comparison for the usual reason, and a null + // guard because a node row can exist with no agent at all. + return $known !== null && hash_equals($known, $secret) ? $installation : null; + } +} diff --git a/app/Services/Anchor/AnchorLivenessService.php b/app/Services/Anchor/AnchorLivenessService.php new file mode 100644 index 00000000000..bf643d18125 --- /dev/null +++ b/app/Services/Anchor/AnchorLivenessService.php @@ -0,0 +1,90 @@ +anchorPublicUrl(); + + // Nothing to probe. A machine still waiting to be approved has no + // address yet, and reporting that as a failed probe would be accurate + // but useless -- there was never a request to fail. + if ($public === null) { + return false; + } + + $url = rtrim($public, '/').'/api/v1/info'; + + try { + $response = Http::timeout(self::TIMEOUT_SECONDS)->get($url); + } catch (\Throwable $exception) { + Log::debug('Anchor liveness probe failed.', [ + 'anchor' => $anchor->id, + 'error' => $exception->getMessage(), + ]); + + return false; + } + + if (! $response->successful()) { + return false; + } + + // `mode` is reported by the Anchor itself; a mismatch means this URL is + // serving a different installation than the one we have on record, so + // it must not count as this Anchor being alive. The heartbeat endpoint + // enforces the same invariant. + if ($response->json('mode') !== $anchor->anchorMode()->value) { + return false; + } + + $min = $response->json('protocol.min'); + $max = $response->json('protocol.max'); + + if (! is_int($min) || ! is_int($max)) { + return false; + } + + $anchor->recordAnchorHeartbeat([ + 'version' => (string) $response->json('version'), + 'protocol_min' => $min, + 'protocol_max' => $max, + 'capabilities' => $response->json('capabilities') ?? [], + ]); + + return true; + } +} diff --git a/app/Services/Anchor/AnchorSchemaService.php b/app/Services/Anchor/AnchorSchemaService.php new file mode 100644 index 00000000000..937d4e16f8c --- /dev/null +++ b/app/Services/Anchor/AnchorSchemaService.php @@ -0,0 +1,135 @@ +> keyed by parameter name + */ + public function forNode(?Node $node): array + { + if (is_null($node)) { + return $this->bundled(); + } + + return Cache::remember( + $this->cacheKey($node), + now()->addMinutes(self::CACHE_MINUTES), + fn () => $this->fetch($node) ?? $this->bundled(), + ); + } + + public function forget(Node $node): void + { + Cache::forget($this->cacheKey($node)); + } + + /** + * The panel's own copy, used when no node can be asked. + */ + public function bundled(): array + { + $path = resource_path('pve/qemu-create-schema.json'); + + $decoded = json_decode((string) @file_get_contents($path), true); + + return is_array($decoded['parameters'] ?? null) ? $decoded['parameters'] : []; + } + + /** + * @return array>|null null when this node cannot answer + */ + private function fetch(Node $node): ?array + { + $base = $node->anchorPublicUrl(); + $secret = $node->anchorSecret(); + $audience = $node->anchorUuid(); + + if (blank($base) || blank($secret) || blank($audience)) { + return null; + } + + try { + $response = Http::timeout(self::TIMEOUT_SECONDS) + ->withToken($this->token($node)) + ->get(rtrim($base, '/').'/api/v1/pve/schema'); + } catch (\Throwable $exception) { + Log::debug('Could not read the Proxmox API schema from Anchor.', [ + 'node' => $node->id, + 'error' => $exception->getMessage(), + ]); + + return null; + } + + if (! $response->successful()) { + return null; + } + + $parameters = $response->json('parameters'); + + // An empty map is not a usable answer, and caching one would hide a + // broken docs package behind a day of silent permissiveness. + return is_array($parameters) && $parameters !== [] ? $parameters : null; + } + + /** + * The work order travels inside the token, as it does for every other Anchor + * call: a captured token can read a schema and nothing else. + */ + private function token(Node $node): string + { + return $this->jwt->issue( + signingKey: (string) $node->anchorSecret(), + audience: (string) $node->anchorUuid(), + identifier: $node->anchorUuid().Str::random(), + claims: [ + 'protocol' => AnchorProtocol::VERSION, + 'schema' => ['action' => 'qemu_create'], + ], + expiresAt: CarbonImmutable::now()->addMinutes(2), + subject: (string) $node->anchorUuid(), + )->toString(); + } + + private function cacheKey(Node $node): string + { + return "pve-schema:qemu-create:{$node->id}"; + } +} diff --git a/app/Services/Anchor/AnchorSelfRegistrationService.php b/app/Services/Anchor/AnchorSelfRegistrationService.php new file mode 100644 index 00000000000..6517b8f011f --- /dev/null +++ b/app/Services/Anchor/AnchorSelfRegistrationService.php @@ -0,0 +1,91 @@ + $report + * + * @throws UnprocessableEntityHttpException when the key cannot admit it + */ + public function register(string $token, AnchorMode $mode, array $report): AnchorEnrollment + { + return DB::transaction(function () use ($token, $mode, $report) { + /* + * Locked because two machines booting from one image present the + * same single-use key at the same moment. Without it both read + * `uses = 0` and both get in, which makes max_uses a suggestion. + */ + $key = AnchorEnrollmentKey::query() + ->where('token_hash', hash('sha256', $token)) + ->lockForUpdate() + ->first(); + + if ($key === null || ! $key->isUsable()) { + // One message for "no such key", "revoked", "expired" and "used + // up": the presenter is unauthenticated, and which of those it + // is tells them something they have not earned the right to know. + throw new UnprocessableEntityHttpException('The enrollment key is invalid or expired.'); + } + + if (! $key->permits($mode)) { + throw new UnprocessableEntityHttpException( + "This enrollment key does not admit an installation in {$mode->value} mode.", + ); + } + + $enrollment = AnchorEnrollment::create([ + 'uuid' => (string) Str::uuid(), + 'name' => $this->name($report, $key), + 'mode' => $mode, + 'secret' => Str::random(64), + 'enrollment_key_id' => $key->id, + 'reported_facts' => $report, + 'enrolled_at' => now(), + ]); + + $key->increment('uses'); + $key->forceFill(['last_used_at' => now()])->save(); + + return $enrollment; + }); + } + + /** + * A name an operator will recognise in the approval queue. + * + * Prefers what the machine calls itself, because that is what the person + * who racked it will search for. Falls back to the key's name plus a + * discriminator, so a rack enrolling from one key does not produce eight + * rows called "Rack 4". + * + * @param array $report + */ + private function name(array $report, AnchorEnrollmentKey $key): string + { + foreach (['hostname', 'pve_node_name'] as $field) { + $value = $report[$field] ?? null; + + if (is_string($value) && trim($value) !== '') { + return Str::limit(trim($value), 191, ''); + } + } + + return Str::limit($key->name, 180, '').' '.Str::lower(Str::random(6)); + } +} diff --git a/app/Services/Anchor/AnchorSessionService.php b/app/Services/Anchor/AnchorSessionService.php new file mode 100644 index 00000000000..d9508526f00 --- /dev/null +++ b/app/Services/Anchor/AnchorSessionService.php @@ -0,0 +1,137 @@ +node; + + if (! $agent->hasAnchor()) { + throw new ConflictHttpException('This server\'s node does not have an Anchor agent installed.'); + } + + $agent->loadMissing('relay'); + $this->ensureCompatible($agent); + $password = $type === ConsoleType::NOVNC ? Str::random(8) : null; + $console = [ + 'type' => $type === ConsoleType::NOVNC ? 'qemu_vnc' : 'qemu_terminal', + 'vm_id' => $server->vmid, + ...($password !== null ? ['password' => $password] : []), + ]; + $expiresAt = CarbonImmutable::now()->addMinute(); + $agentToken = $this->issue( + anchor: $agent, + server: $server, + user: $user, + console: $console, + expiresAt: $expiresAt, + ); + + if ($agent->relay !== null) { + $this->ensureCompatible($agent->relay); + $token = $this->issue( + anchor: $agent->relay, + server: $server, + user: $user, + console: $console, + expiresAt: $expiresAt, + relay: [ + 'url' => $this->websocketUrl($agent), + 'token' => $agentToken, + ], + ); + $endpoint = $agent->relay; + } else { + $token = $agentToken; + $endpoint = $agent; + } + + return new ConsoleSessionData( + url: $this->websocketUrl($endpoint), + token: $token, + protocol: AnchorProtocol::VERSION, + type: $type, + password: $password, + ); + } + + /** @param array $console @param array|null $relay */ + private function issue( + Node|Relay $anchor, + Server $server, + User $user, + array $console, + CarbonImmutable $expiresAt, + ?array $relay = null, + ): string { + return $this->jwt->issue( + signingKey: $anchor->anchorSecret(), + audience: $anchor->anchorUuid(), + identifier: $user->uuid.$server->uuid.$anchor->anchorUuid().Str::random(), + claims: array_filter([ + 'protocol' => AnchorProtocol::VERSION, + 'console' => $console, + 'relay' => $relay, + ], fn (mixed $value) => $value !== null), + expiresAt: $expiresAt, + subject: $user->uuid, + )->toString(); + } + + /** + * An approved Anchor always has an address -- approval is where it is + * established -- so this never fires in practice. It exists because + * "never in practice" is not a type, and a console that declines with a + * sentence beats one that dies on a null deep inside token issuance. + */ + private function websocketUrl(Node|Relay $anchor): string + { + return $anchor->anchorWebsocketUrl() ?? throw new ConflictHttpException( + "Anchor {$anchor->anchorName()} has no address for the panel to reach it on.", + ); + } + + private function ensureCompatible(Node|Relay $anchor): void + { + $compatibility = $anchor->anchorCompatibility(); + + // A stale heartbeat does not prove the Anchor is down — it may just be + // unable to reach us. Before refusing the session, try reaching it the + // other way round; a successful probe records a heartbeat of its own, + // so the verdict has to be recomputed from the refreshed model rather + // than reused from above. + if ($compatibility === AnchorCompatibility::OFFLINE) { + $this->liveness->refresh($anchor); + $compatibility = $anchor->anchorCompatibility(); + } + + if ($compatibility !== AnchorCompatibility::COMPATIBLE) { + throw new ConflictHttpException( + "Anchor {$anchor->anchorName()} is not online with a compatible protocol version.", + ); + } + } +} diff --git a/app/Services/Anchor/IssuedEnrollmentKey.php b/app/Services/Anchor/IssuedEnrollmentKey.php new file mode 100644 index 00000000000..7da9ddfb0d1 --- /dev/null +++ b/app/Services/Anchor/IssuedEnrollmentKey.php @@ -0,0 +1,20 @@ + $abilities + */ + public function handle(User $user, string $name, array $abilities = ['*']): NewAccessToken + { + $token = new PersonalAccessToken([ + 'type' => ApiKeyType::ACCOUNT, + 'name' => $name, + 'token' => hash('sha256', $plainTextToken = Str::random(40)), + 'abilities' => $abilities, + ]); + + $token->tokenable()->associate($user); + $token->save(); + + return new NewAccessToken($token, $token->getKey().'|'.$plainTextToken); + } +} diff --git a/app/Services/Api/CreateApplicationTokenService.php b/app/Services/Api/CreateApplicationTokenService.php new file mode 100644 index 00000000000..0f43fd28a72 --- /dev/null +++ b/app/Services/Api/CreateApplicationTokenService.php @@ -0,0 +1,41 @@ + $abilities + * @param list $allowedNetworks + */ + public function handle( + User $creator, + string $name, + array $abilities = ['*'], + array $allowedNetworks = [], + ): NewAccessToken { + $token = new PersonalAccessToken([ + 'type' => ApiKeyType::APPLICATION, + 'name' => $name, + 'token' => hash('sha256', $plainTextToken = Str::random(40)), + 'abilities' => $abilities, + 'allowed_networks' => $allowedNetworks, + 'created_by' => $creator->getKey(), + ]); + + $token->tokenable()->associate(SystemActor::instance()); + $token->save(); + + return new NewAccessToken($token, $token->getKey().'|'.$plainTextToken); + } +} diff --git a/app/Services/Api/JWTService.php b/app/Services/Api/JWTService.php index dff75c05d09..14595401c85 100644 --- a/app/Services/Api/JWTService.php +++ b/app/Services/Api/JWTService.php @@ -1,133 +1,102 @@ $claims Additional claims to embed. */ - public function setClaims(array $claims): self - { - $this->claims = $claims; - - return $this; - } - - /** - * Attaches a user to the JWT being created and will automatically inject the - * "user_uuid" key into the final claims array with the user's UUID. - */ - public function setUser(User $user): self - { - $this->user = $user; - - return $this; - } - - public function setExpiresAt(\DateTimeImmutable $date): self - { - $this->expiresAt = $date; - - return $this; - } - - public function setSubject(string $subject): self - { - $this->subject = $subject; - - return $this; - } - - /** - * @param string $key - * @param string $permittedFor A connection address - * @param string|null $identifiedBy - * @param string $algorithm - * @return Plain - */ - public function handle(string $key, string $permittedFor, ?string $identifiedBy, string $algorithm = 'sha256'): Plain - { - $identifier = hash($algorithm, $identifiedBy); - $config = Configuration::forSymmetricSigner(new Sha256(), InMemory::plainText($key)); + public function issue( + string $signingKey, + string $audience, + string $identifier, + array $claims = [], + ?DateTimeImmutable $expiresAt = null, + ?string $subject = null, + ): Plain { + $config = $this->configFor($signingKey); + $now = CarbonImmutable::now(); + $jti = hash('sha256', $identifier); $builder = $config->builder() ->issuedBy(config('app.url')) - ->permittedFor($permittedFor) - ->identifiedBy($identifier) - ->withHeader('jti', $identifier) - ->issuedAt(CarbonImmutable::now()) - ->canOnlyBeUsedAfter(CarbonImmutable::now()->subMinutes(5)); - - if ($this->expiresAt) { - $builder = $builder->expiresAt($this->expiresAt); + ->permittedFor($audience) + ->identifiedBy($jti) + ->withHeader('jti', $jti) + ->issuedAt($now) + ->canOnlyBeUsedAfter($now->subMinutes(5)) + ->withClaim('unique_id', Str::random()); + + if ($expiresAt !== null) { + $builder = $builder->expiresAt($expiresAt); } - if (!empty($this->subject)) { - $builder = $builder->relatedTo($this->subject)->withHeader('sub', $this->subject); + if ($subject !== null) { + $builder = $builder->relatedTo($subject); } - foreach ($this->claims as $key => $value) { - $builder = $builder->withClaim($key, $value); + foreach ($claims as $name => $value) { + $builder = $builder->withClaim($name, $value); } - if (!is_null($this->user)) { - $builder = $builder - ->withClaim('user_uuid', $this->user->uuid); + $token = $builder->getToken($config->signer(), $config->signingKey()); + + if (! $token instanceof Plain) { + throw new \LogicException('Expected JWT builder to return a plain token.'); } - return $builder - ->withClaim('unique_id', Str::random()) - ->getToken($config->signer(), $config->signingKey()); + return $token; } - public function decode(string $key, string $token): UnencryptedToken + public function decode(string $signingKey, string $token): UnencryptedToken { - $config = Configuration::forSymmetricSigner(new Sha256(), InMemory::plainText($key)); + $config = $this->configFor($signingKey); try { $parsedToken = $config->parser()->parse($token); - } catch (CannotDecodeContent | InvalidTokenStructure | UnsupportedHeaderFound $exception) { + } catch (CannotDecodeContent|InvalidTokenStructure|UnsupportedHeaderFound $exception) { throw new InvalidJWTException($exception); } assert($parsedToken instanceof UnencryptedToken); - if (!$config->validator()->validate( + // StrictValidAt alone only checks the token is well-formed and unexpired, which would + // accept a forged token with arbitrary claims. SignedWith confirms it was signed with our key. + if (! $config->validator()->validate( $parsedToken, new StrictValidAt(new Clock), - new SignedWith( - $config->signer(), - $config->signingKey() - ) + new SignedWith($config->signer(), $config->signingKey()), )) { throw new InvalidJWTException; } return $parsedToken; } + + private function configFor(string $signingKey): Configuration + { + return Configuration::forSymmetricSigner(new Sha256, InMemory::plainText($signingKey)); + } } diff --git a/app/Services/Audit/AuditLogger.php b/app/Services/Audit/AuditLogger.php new file mode 100644 index 00000000000..f031e49a8c8 --- /dev/null +++ b/app/Services/Audit/AuditLogger.php @@ -0,0 +1,185 @@ + 'start']); + * + * Scoped to the request (see {@see AuditServiceProvider}) because the batch counter + * is per-request state. + * + * See docs/audit-log-plan.md for why this exists rather than spatie/laravel-activitylog. + */ +class AuditLogger +{ + /** Nesting depth of the current batch; the UUID is cleared when it returns to zero. */ + private int $batchDepth = 0; + + private ?string $batchUuid = null; + + public function __construct( + private readonly AuthFactory $auth, + private readonly Application $app, + ) {} + + /** + * Records an action. Call this *after* the action has succeeded, or inside its transaction + * where one exists — an action that rolls back must not leave an audit row behind. + * + * @param Model|null $subject what was acted on; null only for panel-wide events like settings + * @param array $properties event-specific detail, rendered by the frontend + * @param Model|null $actor overrides the authenticated user, for jobs and console commands + */ + public function record( + AuditEvent $event, + ?Model $subject = null, + array $properties = [], + ?Model $actor = null, + ): ?AuditLog { + try { + return $this->write($event, $subject, $properties, $actor); + } catch (Throwable $exception) { + // An audit failure must never take down the action being audited. Outside production + // it still throws, so a broken call site fails loudly in development and in tests. + if (config('app.env') !== 'production') { + throw $exception; + } + + Log::error('Failed to record audit entry', [ + 'event' => $event->value, + 'exception' => $exception, + ]); + + return null; + } + } + + /** + * Runs the callback with every entry recorded inside it sharing one batch UUID, so the UI can + * collapse "deleted 12 rules" into a single line. Nests safely. + */ + public function batch(Closure $callback): mixed + { + if ($this->batchDepth === 0) { + $this->batchUuid = Uuid::uuid4()->toString(); + } + + $this->batchDepth++; + + try { + return $callback(); + } finally { + $this->batchDepth--; + + if ($this->batchDepth === 0) { + $this->batchUuid = null; + } + } + } + + private function write( + AuditEvent $event, + ?Model $subject, + array $properties, + ?Model $actor, + ): AuditLog { + $log = new AuditLog([ + 'event' => $event, + 'batch' => $this->batchUuid, + 'properties' => $properties, + 'api_token_id' => $this->apiTokenId(), + 'ip' => $this->request()?->ip(), + // Truncated rather than rejected: a hostile or merely eccentric UA string must not be + // able to fail somebody's power action. + 'user_agent' => $this->userAgent(), + ]); + + $actor ??= $this->auth->guard()->user(); + + if ($actor instanceof Model) { + $log->actor()->associate($actor); + $log->actor_label = $this->labelFor($actor); + } + + if ($subject !== null) { + $log->subject()->associate($subject); + } + + $log->save(); + + return $log; + } + + /** + * A human-readable snapshot of who acted, stored alongside the morph because the morph goes + * null when the actor is deleted. Prefers the name, falls back to the email, and finally to a + * type/id pair so the row is never anonymous. + */ + private function labelFor(Model $actor): ?string + { + $label = $actor->getAttribute('name') ?? $actor->getAttribute('email'); + + if (is_string($label) && $label !== '') { + return mb_substr($label, 0, 255); + } + + return class_basename($actor).'#'.$actor->getKey(); + } + + /** + * The token behind this request, when there is one. Note that the resolved user may be a + * SystemActor rather than a User (panel-wide application tokens); both use HasApiTokens, so + * `currentAccessToken()` is available either way. + */ + private function apiTokenId(): ?int + { + $user = $this->auth->guard()->user(); + + if ($user === null || ! method_exists($user, 'currentAccessToken')) { + return null; + } + + $token = $user->currentAccessToken(); + + return $token?->getKey(); + } + + private function userAgent(): ?string + { + $agent = $this->request()?->userAgent(); + + return $agent === null ? null : mb_substr($agent, 0, 500); + } + + /** + * The HTTP request behind this action, or null when there isn't one. + * + * Gated on whether a route has actually been matched. Outside a real request the container + * still hands back a synthetic Request whose ip() is 127.0.0.1 and whose REMOTE_ADDR is set, + * and an audit trail claiming a scheduled prune came from localhost is worse than one that + * records no IP at all. runningInConsole() cannot make this distinction (it is also true under + * the test runner) and neither can REMOTE_ADDR; a resolved route can. + */ + private function request(): ?Request + { + $request = $this->app->make(Request::class); + + return $request->route() === null ? null : $request; + } +} diff --git a/app/Services/Auth/OAuthAuthenticationService.php b/app/Services/Auth/OAuthAuthenticationService.php new file mode 100644 index 00000000000..b395b634bd9 --- /dev/null +++ b/app/Services/Auth/OAuthAuthenticationService.php @@ -0,0 +1,187 @@ + + */ + public function enabledProviders(): array + { + $providers = []; + + foreach ((array) config('oauth.providers', []) as $driver => $meta) { + if ($this->isEnabled($driver)) { + $providers[$driver] = (string) ($meta['label'] ?? Str::title($driver)); + } + } + + return $providers; + } + + /** + * Assert the driver is a configured, enabled provider, or throw. Callers use this + * to gate both the redirect and callback endpoints so a disabled/unknown provider + * never reaches Socialite. + */ + public function ensureEnabled(string $provider): void + { + if (! $this->isEnabled($provider)) { + throw new OAuthProviderNotEnabledException($provider); + } + } + + private function isEnabled(string $provider): bool + { + return (bool) config("oauth.providers.{$provider}.enabled") + && filled(config("services.{$provider}.client_id")); + } + + /** + * Resolve the Convoy user a federated sign-in should authenticate as, applying the + * configured link/registration policy: + * 1. an existing connection for this provider identity wins outright; + * 2. otherwise, when enabled, link to an existing user by *verified* email; + * 3. otherwise, when registration is enabled, provision a new non-admin user; + * 4. otherwise refuse (the door is closed). + */ + public function resolveForLogin(string $provider, SocialiteUser $socialiteUser): User + { + $connection = $this->findConnection($provider, $socialiteUser); + + if ($connection instanceof OAuthConnection) { + $this->touchConnection($connection, $socialiteUser); + + /** @var User $user */ + $user = $connection->user; + + return $user; + } + + if (config('oauth.link_by_verified_email') && $this->emailIsVerified($provider, $socialiteUser)) { + $user = User::query()->where('email', '=', $socialiteUser->getEmail())->first(); + + if ($user instanceof User) { + $this->createConnection($user, $provider, $socialiteUser); + + return $user; + } + } + + if (config('oauth.registration')) { + return $this->provisionUser($provider, $socialiteUser); + } + + throw new OAuthAccountNotProvisionedException; + } + + /** + * Link a provider identity to an already-authenticated user (the account-settings + * "Connect" flow). Idempotent for the same user; conflicts if the identity is owned + * by someone else. + */ + public function linkToUser(User $user, string $provider, SocialiteUser $socialiteUser): OAuthConnection + { + $connection = $this->findConnection($provider, $socialiteUser); + + if ($connection instanceof OAuthConnection) { + if ($connection->user_id !== $user->id) { + throw new OAuthIdentityAlreadyLinkedException; + } + + $this->touchConnection($connection, $socialiteUser); + + return $connection; + } + + return $this->createConnection($user, $provider, $socialiteUser); + } + + private function findConnection(string $provider, SocialiteUser $socialiteUser): ?OAuthConnection + { + return OAuthConnection::query() + ->where('provider', '=', $provider) + ->where('provider_id', '=', (string) $socialiteUser->getId()) + ->first(); + } + + private function createConnection(User $user, string $provider, SocialiteUser $socialiteUser): OAuthConnection + { + return $user->oauthConnections()->create([ + 'provider' => $provider, + 'provider_id' => (string) $socialiteUser->getId(), + 'name' => $socialiteUser->getName(), + 'email' => $socialiteUser->getEmail(), + 'last_used_at' => now(), + ]); + } + + private function touchConnection(OAuthConnection $connection, SocialiteUser $socialiteUser): void + { + $connection->forceFill([ + 'name' => $socialiteUser->getName(), + 'email' => $socialiteUser->getEmail(), + 'last_used_at' => now(), + ])->save(); + } + + private function provisionUser(string $provider, SocialiteUser $socialiteUser): User + { + $email = $socialiteUser->getEmail(); + + if (! $this->emailIsVerified($provider, $socialiteUser) || blank($email)) { + // Never auto-create an account from an unverified/absent email — that would let + // anyone claim a colleague's address at their IdP and land in a fresh Convoy user. + throw new OAuthAccountNotProvisionedException; + } + + $user = new User; + $user->forceFill([ + 'name' => $socialiteUser->getName() ?: Str::before($email, '@'), + 'email' => $email, + // A verified IdP is the credential; the password is a throwaway they never use. + 'password' => Str::random(24).'aA1!', + 'root_admin' => false, + 'email_verified_at' => now(), + ])->save(); + + $this->createConnection($user, $provider, $socialiteUser); + + return $user; + } + + private function emailIsVerified(string $provider, SocialiteUser $socialiteUser): bool + { + if (blank($socialiteUser->getEmail())) { + return false; + } + + if (in_array($provider, self::IMPLICITLY_VERIFIED_EMAIL_PROVIDERS, true)) { + return true; + } + + $raw = method_exists($socialiteUser, 'getRaw') ? $socialiteUser->getRaw() : []; + + return filter_var($raw['email_verified'] ?? false, FILTER_VALIDATE_BOOLEAN); + } +} diff --git a/app/Services/Auth/SessionRevocationService.php b/app/Services/Auth/SessionRevocationService.php new file mode 100644 index 00000000000..babd9ad0f1c --- /dev/null +++ b/app/Services/Auth/SessionRevocationService.php @@ -0,0 +1,48 @@ +getHandler()->destroy($record->session_id); + $record->delete(); + } + + /** + * Revoke every session belonging to a user. Call before the user row is deleted, while the + * metadata rows (and thus their session ids) still exist. + */ + public function revokeAllForUser(User $user): void + { + $this->revokeForUser($user); + } + + /** + * Revoke every session belonging to a user except the one making the request, so an action can + * evict every other device without logging the actor out of the tab they are performing it in. + */ + public function revokeOtherSessionsForUser(User $user, string $exceptSessionId): void + { + $this->revokeForUser($user, $exceptSessionId); + } + + private function revokeForUser(User $user, ?string $exceptSessionId = null): void + { + SessionRecord::query() + ->where('user_id', $user->getKey()) + ->when($exceptSessionId !== null, fn ($query) => $query->where('session_id', '!=', $exceptSessionId)) + ->get() + ->each(fn (SessionRecord $record) => $this->revoke($record)); + } +} diff --git a/app/Services/Backups/BackupCreationService.php b/app/Services/Backups/BackupCreationService.php index c655bbb2cfe..3d3f49e7b84 100644 --- a/app/Services/Backups/BackupCreationService.php +++ b/app/Services/Backups/BackupCreationService.php @@ -1,75 +1,85 @@ 0) { - $previous = $this->eloquentRepository->getBackupsGeneratedDuringTimespan( - $server->id, $period, - ); + $previous = $server->backups() + ->createdWithinSeconds($period) + ->latest('created_at') + ->get(); if ($previous->count() >= $limit) { $message = sprintf( - 'Only %d backups may be generated within a %d second span of time.', $limit, + 'Only %d backups may be generated within a %d second span of time.', + $limit, $period, ); throw new TooManyRequestsHttpException( - CarbonImmutable::now()->diffInSeconds( + (int) CarbonImmutable::now()->diffInSeconds( $previous->last()->created_at->addSeconds($period), - ), $message, + ), + $message, ); } } - $successful = $this->eloquentRepository->getNonFailedBackups($server); - if (!$server->backup_limit || $successful->count() >= $server->backup_limit) { - if (isset($server->backup_limit)) { - throw new TooManyBackupsException((int)$server->backup_limit); - } + $successful = $server->backups()->nonFailed(); + if ($server->backup_count_limit >= 0 && $successful->count() >= $server->backup_count_limit) { + throw new TooManyBackupsException($server->backup_count_limit); + } + + $storage = $server->node->backupStorage(); + if (is_null($storage)) { + throw new ConflictHttpException('No backup-capable storage is configured for this node.'); } return $this->connection->transaction( - function () use ($server, $name, $mode, $compressionType, $isLocked) { - $backup = $this->eloquentRepository->create([ + function () use ($server, $name, $mode, $compressionType, $isLocked, $storage) { + $backup = Backup::create([ 'uuid' => Uuid::uuid4()->toString(), 'server_id' => $server->id, + 'storage_id' => $storage->id, 'name' => $name, 'is_locked' => $isLocked, + 'size' => 0, ]); - $upid = $this->proxmoxRepository->setServer($server)->backup( - $mode, $compressionType, + $upid = $this->proxmoxClient->setServer($server)->backup( + $mode, + $compressionType, + $storage->name, ); - MonitorBackupJob::dispatch($backup->id, $upid); + MonitorBackupJob::dispatch($backup, $upid); return $backup; }, diff --git a/app/Services/Backups/BackupDeletionService.php b/app/Services/Backups/BackupDeletionService.php index 63d77c3f33c..4c19f214bcd 100644 --- a/app/Services/Backups/BackupDeletionService.php +++ b/app/Services/Backups/BackupDeletionService.php @@ -1,28 +1,27 @@ is_locked && ($backup->is_successful && !is_null($backup->completed_at))) { - throw new BackupLockedException(); + if ($backup->is_locked && is_null($backup->error_code) && ! is_null($backup->completed_at)) { + throw new BackupLockedException; } $this->connection->transaction(function () use ($backup) { - $this->proxmoxRepository->setServer($backup->server)->delete($backup); + $this->proxmoxClient->setServer($backup->server)->delete($backup); $backup->delete(); }); diff --git a/app/Services/Backups/BackupMonitorService.php b/app/Services/Backups/BackupMonitorService.php deleted file mode 100644 index 57b4724ef0d..00000000000 --- a/app/Services/Backups/BackupMonitorService.php +++ /dev/null @@ -1,82 +0,0 @@ -repository->setServer($backup->server)->getStatus($upid); - $logs = $this->repository->setServer($backup->server)->getLog($upid); - - // get the filename of the backup (e.g. vzdump-qemu-101-2021_01_01-00_00_00.vma.zstd) - $fileName = null; - foreach ($logs as $log) { - if (preg_match("/INFO: creating vzdump archive '(.+)'/s", $log['t'], $matches)) { - $fileName = Arr::last(explode('/', $matches[1])); - } - } - - // if it's running we won't do anything to the eloquent backup record for now - if (Arr::get($status, 'status') === 'running') { - if ($callback) { - $callback(); - } - - return; - } - - if (Str::lower(Arr::get($status, 'exitstatus')) === 'ok') { - $archives = $this->backupRepository->setServer($backup->server)->getBackups(); - $archive = collect($archives)->where( - 'volid', "{$backup->server->node->backup_storage}:backup/{$fileName}", - )->first(); - - $backup->update([ - 'is_successful' => true, - 'file_name' => $fileName, - 'size' => Arr::get($archive, 'size', 0), - 'completed_at' => Carbon::now(), - ]); - } else { - $backup->update([ - 'is_successful' => false, - 'completed_at' => Carbon::now(), - ]); - } - } - - public function checkRestorationProgress(Server $server, string $upid, ?Closure $callback = null, - ) - { - $status = $this->repository->setServer($server)->getStatus($upid); - - if (Arr::get($status, 'status') === 'running') { - if ($callback) { - $callback(); - } - - return; - } - - $server->update([ - 'status' => null, - ]); - } -} diff --git a/app/Services/Backups/PurgeBackupsService.php b/app/Services/Backups/PurgeBackupsService.php index 32f6dcd8efb..a8e45c0977b 100644 --- a/app/Services/Backups/PurgeBackupsService.php +++ b/app/Services/Backups/PurgeBackupsService.php @@ -1,23 +1,19 @@ backupRepository->getNonFailedBackups($server)->get(); + $backups = $server->backups()->nonFailed()->get(); $backups->each(function (Backup $backup) { $this->backupDeletionService->handle($backup); diff --git a/app/Services/Backups/RestoreFromBackupService.php b/app/Services/Backups/RestoreFromBackupService.php index 2fc86a9116b..b8f94470acd 100644 --- a/app/Services/Backups/RestoreFromBackupService.php +++ b/app/Services/Backups/RestoreFromBackupService.php @@ -1,43 +1,41 @@ status)) { + if ($server->isSuspended() || ! $server->lifecycle->isReady()) { throw new BadRequestHttpException( 'This server is not currently in a state that allows for a backup to be restored.', ); } - $stateData = $this->serverRepository->setServer($server)->getState(); - if ($stateData->state !== State::STOPPED) { + $stateData = $this->serverClient->setServer($server)->getState(); + if ($stateData->powerState !== PowerState::STOPPED) { throw new BadRequestHttpException( 'The server needs to be stopped before a backup can be restored.', ); } - if (!$backup->successful && is_null($backup->completed_at)) { + if ($backup->error_code !== null || $backup->completed_at === null) { throw new BadRequestHttpException( 'This backup cannot be restored at this time: not completed or failed.', ); @@ -45,12 +43,12 @@ public function handle(Server $server, Backup $backup) $this->connection->transaction(function () use ($server, $backup) { $server->update([ - 'status' => Status::RESTORING_BACKUP->value, + 'lifecycle' => ServerLifecycle::RESTORING_BACKUP->value, ]); - $upid = $this->proxmoxRepository->setServer($server)->restore($backup); + $upid = $this->proxmoxClient->setServer($server)->restore($backup); - MonitorBackupRestorationJob::dispatch($server->id, $upid); + MonitorBackupRestorationJob::dispatch($server, $upid); }); } } diff --git a/app/Services/Coterm/CotermJWTService.php b/app/Services/Coterm/CotermJWTService.php deleted file mode 100644 index e8e66004971..00000000000 --- a/app/Services/Coterm/CotermJWTService.php +++ /dev/null @@ -1,41 +0,0 @@ -node->coterm, Coterm::class, - 'The server\'s node does not have a Coterm instance.', - ); - - $token = $this->JWTService - ->setExpiresAt(CarbonImmutable::now()->addMinute()) - ->setUser($user) - ->setClaims([ - 'server_uuid' => $server->uuid, - 'console_type' => $consoleType->value, - ]) - ->handle( - $server->node->coterm->token, $server->node->getCotermConnectionAddress(), - $user->uuid . $server->uuid, - ); - - return $token; - } -} \ No newline at end of file diff --git a/app/Services/Coterm/CotermTokenCreationService.php b/app/Services/Coterm/CotermTokenCreationService.php deleted file mode 100644 index a416fa51fbb..00000000000 --- a/app/Services/Coterm/CotermTokenCreationService.php +++ /dev/null @@ -1,26 +0,0 @@ - Str::random(Coterm::COTERM_TOKEN_LENGTH), - 'token_id' => Str::random(Coterm::COTERM_TOKEN_ID_LENGTH), - ]; - } -} \ No newline at end of file diff --git a/app/Services/ISOs/ISOResidencyService.php b/app/Services/ISOs/ISOResidencyService.php new file mode 100644 index 00000000000..52f1f5db314 --- /dev/null +++ b/app/Services/ISOs/ISOResidencyService.php @@ -0,0 +1,113 @@ +client->setNode($node)->getFileNames( + StorageContentType::ISO, + $this->storageFor($node)->name, + ); + + return in_array($iso->file_name, $names, true); + } + + /** + * Start the download if this node does not have the file yet. + * + * @return ?string Task UPID, or null when the node already has it + * + * @throws RequestException + * @throws ConnectionException + */ + public function ensureResident(Node $node, ISO $iso): ?string + { + if ($this->isResident($node, $iso)) { + return null; + } + + return $this->client->setNode($node)->download( + contentType: StorageContentType::ISO, + storage: $this->storageFor($node)->name, + fileName: $iso->file_name, + link: $this->urlFor($iso), + checksumData: filled($iso->sha256) + ? new ChecksumData(checksum: $iso->sha256, algorithm: ChecksumAlgorithm::SHA256) + : null, + ); + } + + /** + * The volume string a mounted copy takes on this node. + */ + public function volume(Node $node, ISO $iso): string + { + return sprintf( + '%s:%s/%s', + $this->storageFor($node)->name, + StorageContentType::ISO->toProxmoxString(), + $iso->file_name, + ); + } + + /** + * A link the operator gave us, or a signed one for a file we host. + */ + private function urlFor(ISO $iso): string + { + if (! $iso->isHosted()) { + return $iso->url ?? throw new ConflictHttpException( + 'This ISO has neither a URL nor an uploaded file.', + ); + } + + return Filesystem::disk($this->resolver->diskName())->temporaryUrl( + (string) $iso->path, + now()->addMinutes((int) config('convoy.artifacts.url_ttl_minutes', 120)), + ); + } + + private function storageFor(Node $node): Storage + { + return $node->isoStorage() ?? throw new ConflictHttpException( + "No storage on {$node->name} accepts ISOs.", + ); + } +} diff --git a/app/Services/ISOs/ISOService.php b/app/Services/ISOs/ISOService.php new file mode 100644 index 00000000000..6f45c1034bc --- /dev/null +++ b/app/Services/ISOs/ISOService.php @@ -0,0 +1,74 @@ + $attributes + */ + public function create(array $attributes): ISO + { + return ISO::create($attributes); + } + + /** + * Remove an ISO from the library, and the file if the panel was hosting it. + * + * Copies already sitting on nodes are deliberately left alone. Deleting + * them would mean reaching into every node the panel knows about, some of + * which will be unreachable, to reclaim space PVE already treats as a cache + * -- and a half-completed sweep is worse than none. They are ordinary ISO + * files an operator can prune from Proxmox. + */ + public function delete(ISO $iso): void + { + if ($iso->isHosted()) { + Filesystem::disk($this->resolver->diskName())->delete((string) $iso->path); + } + + $iso->delete(); + } + + /** + * File names already on a node's ISO storage. + * + * Used by the admin UI to offer ISOs a node happens to hold, so an operator + * who uploaded one to Proxmox by hand can register it without re-uploading. + * + * @return array + */ + public function fileNamesOn(Node $node): array + { + $storage = $node->isoStorage(); + + if (is_null($storage)) { + return []; + } + + return $this->client->setNode($node)->getFileNames( + StorageContentType::ISO, + $storage->name, + ); + } +} diff --git a/app/Services/Images/ImageInspector.php b/app/Services/Images/ImageInspector.php new file mode 100644 index 00000000000..c4fdcc19abd --- /dev/null +++ b/app/Services/Images/ImageInspector.php @@ -0,0 +1,94 @@ + 0 ? (int) $unpacked[1] : null; + } + + public function virtualSizeOfFile(string $path): ?int + { + $handle = @fopen($path, 'rb'); + + if ($handle === false) { + return null; + } + + try { + return $this->virtualSizeFromHeader((string) fread($handle, self::HEADER_BYTES)); + } finally { + fclose($handle); + } + } + + /** + * The same read, over HTTP, for an image the operator hosts themselves. + * + * One ranged request for the first 32 bytes: an origin that honours it + * costs nothing, and one that does not simply leaves the size unknown for + * the admin to supply. Downloading gigabytes to read a header would not be + * a reasonable trade either way. + */ + public function virtualSizeOfUrl(string $url): ?int + { + try { + $response = Http::timeout(10) + ->withHeaders(['Range' => 'bytes=0-'.(self::HEADER_BYTES - 1)]) + ->get($url); + } catch (\Throwable $exception) { + Log::debug('Could not read a disk image header over HTTP.', [ + 'error' => $exception->getMessage(), + ]); + + return null; + } + + if (! $response->successful()) { + return null; + } + + return $this->virtualSizeFromHeader($response->body()); + } + + public function sha256OfFile(string $path): string + { + return (string) hash_file('sha256', $path); + } +} diff --git a/app/Services/Images/ImageResidencyService.php b/app/Services/Images/ImageResidencyService.php new file mode 100644 index 00000000000..55166370e67 --- /dev/null +++ b/app/Services/Images/ImageResidencyService.php @@ -0,0 +1,134 @@ + + */ + public function volids(Node $node, ImageVersion $version): array + { + $storage = $this->storageFor($node); + + return $version->diskSet() + ->mapWithKeys(fn (ImageDiskData $disk) => [ + $disk->role->value => sprintf( + '%s:%s/%s', + $storage->name, + StorageContentType::IMPORT->toProxmoxString(), + $this->resolver->fileNameFor($disk), + ), + ]) + ->all(); + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function isResident(Node $node, ImageVersion $version): bool + { + return $this->missingDisks($node, $version)->isEmpty(); + } + + /** + * Start a download for every disk this node is missing. + * + * @return array Task UPIDs, empty when the node already has everything + * + * @throws RequestException + * @throws ConnectionException + */ + public function ensureResident(Node $node, ImageVersion $version): array + { + $storage = $this->storageFor($node); + + return $this->missingDisks($node, $version) + ->map(fn (ImageDiskData $disk) => $this->client->setNode($node)->download( + contentType: StorageContentType::IMPORT, + storage: $storage->name, + fileName: $this->resolver->fileNameFor($disk), + link: $this->resolver->urlFor($disk), + checksumData: new ChecksumData( + checksum: $disk->sha256, + algorithm: ChecksumAlgorithm::SHA256, + ), + )) + ->values() + ->all(); + } + + /** + * @return Collection + * + * @throws RequestException + * @throws ConnectionException + */ + private function missingDisks(Node $node, ImageVersion $version) + { + $storage = $this->storageFor($node); + + $present = $this->client->setNode($node)->getFileNames( + StorageContentType::IMPORT, + $storage->name, + ); + + return $version->diskSet()->reject( + fn (ImageDiskData $disk) => in_array($this->resolver->fileNameFor($disk), $present, true), + ); + } + + /** + * PVE keeps the `import` content type off by default, so this is a real and + * common configuration gap rather than a defensive null check. Saying which + * node and what to enable is the difference between an admin fixing it in a + * minute and filing a bug about builds hanging. + */ + private function storageFor(Node $node) + { + return $node->importStorage() ?? throw new ConflictHttpException( + "No storage on {$node->name} accepts disk images. Add `Import` to a storage's content types in Proxmox.", + ); + } +} diff --git a/app/Services/Images/ImageSourceResolver.php b/app/Services/Images/ImageSourceResolver.php new file mode 100644 index 00000000000..75a8c4c0a12 --- /dev/null +++ b/app/Services/Images/ImageSourceResolver.php @@ -0,0 +1,66 @@ +isHosted()) { + return $disk->url ?? throw new ConflictHttpException( + 'This image disk has neither a URL nor an uploaded file.', + ); + } + + $disk_ = Filesystem::disk($this->diskName()); + + // A local filesystem only signs URLs when the disk is served, which is + // exactly what the shipped config turns on. Saying so beats handing + // Proxmox a link it will fetch an HTML error page from. + if (! method_exists($disk_, 'temporaryUrl')) { + throw new ConflictHttpException( + 'The artifacts filesystem cannot produce download links. Set `serve` on the disk, or host the file yourself.', + ); + } + + return $disk_->temporaryUrl( + (string) $disk->path, + now()->addMinutes((int) config('convoy.artifacts.url_ttl_minutes', 120)), + ); + } + + /** + * The content-addressed name this disk takes on a node. + * + * Named after the hash rather than the image, so two definitions built from + * the same disk share one file, a rebuild never collides with the build it + * replaces, and a node can answer "do I already have this?" by name alone. + * The `.qcow2` suffix is not decoration: PVE refuses an import file whose + * extension it does not recognise. + */ + public function fileNameFor(ImageDiskData $disk): string + { + return "image-{$disk->sha256}.{$disk->format}"; + } + + public function diskName(): string + { + return (string) config('convoy.artifacts.disk', 'artifacts'); + } +} diff --git a/app/Services/Images/OsProfiles.php b/app/Services/Images/OsProfiles.php new file mode 100644 index 00000000000..6edbc7ea048 --- /dev/null +++ b/app/Services/Images/OsProfiles.php @@ -0,0 +1,85 @@ + 'scsi0', + 'cloudinit_slot' => 'ide2', + 'machine' => 'q35', + 'scsihw' => 'virtio-scsi-single', + 'cpu' => 'host', + 'agent' => '1', + ]; + + public static function isWindows(string $ostype): bool + { + return str_starts_with($ostype, 'win') + || str_starts_with($ostype, 'w2k') + || in_array($ostype, ['wvista', 'wxp'], true); + } + + /** + * `machine` is never a version-pinned value like `pc-q35-11.0`: a pin names + * the QEMU of whichever machine built the image and hard-fails on a node + * running an older one. + */ + public static function defaults(string $ostype): array + { + return array_merge(self::COMMON, [ + // Windows images ship as OVMF with a varstore beside them; anything + // else boots fine on SeaBIOS and does not need one. + 'bios' => self::isWindows($ostype) ? 'ovmf' : 'seabios', + ]); + } + + /** + * An unset key inherits rather than clears, which is what makes the admin + * form safe to show in full while asking for none of it. A key set to null + * is treated as "not set" for the same reason. + */ + public static function merge(string $ostype, array $overlay): array + { + return array_merge( + self::defaults($ostype), + array_filter($overlay, fn ($value) => ! is_null($value)), + ); + } + + /** + * The overlay with the meta keys stripped -- what actually reaches Proxmox. + */ + public static function proxmoxKeys(array $hardware): array + { + return array_diff_key($hardware, array_flip(self::META_KEYS)); + } +} diff --git a/app/Services/Isos/IsoMonitorService.php b/app/Services/Isos/IsoMonitorService.php deleted file mode 100644 index 9ad442a325b..00000000000 --- a/app/Services/Isos/IsoMonitorService.php +++ /dev/null @@ -1,42 +0,0 @@ -repository->setNode($iso->node)->getStatus($upid); - - if (Arr::get($status, 'status') === 'running') { - if ($callback) { - $callback(); - } - - return; - } - - if (Str::lower(Arr::get($status, 'exitstatus')) === 'ok') { - $iso->update([ - 'is_successful' => true, - 'completed_at' => Carbon::now(), - ]); - } else { - $iso->update([ - 'is_successful' => false, - 'completed_at' => Carbon::now(), - ]); - } - } -} diff --git a/app/Services/Isos/IsoService.php b/app/Services/Isos/IsoService.php deleted file mode 100644 index f6e31f735f7..00000000000 --- a/app/Services/Isos/IsoService.php +++ /dev/null @@ -1,76 +0,0 @@ -repository->setNode($node)->getFileMetadata($link); - - return $this->connection->transaction( - function () use ( - $queriedFileMetadata, $node, $hidden, $fileName, $link, $name, $checksumData, - ) { - $iso = ISO::create([ - 'node_id' => $node->id, - 'name' => $name, - 'file_name' => $fileName ?? $queriedFileMetadata->file_name, - 'hidden' => $hidden, - 'size' => $queriedFileMetadata->size, - ]); - - $upid = $this->repository->setNode($node)->download( - ContentType::ISO, $iso->file_name, $link, true, $checksumData, - ); - - MonitorIsoDownloadJob::dispatch($iso->id, $upid); - - return $iso; - }, - ); - } - - public function getIso(Node $node, string $fileName): ?IsoData - { - $isos = $this->repository->setNode($node)->getIsos(); - - return $isos->where('file_name', '=', $fileName)->first(); - } - - public function delete(Node $node, ISO $iso): void - { - if (is_null($iso->completed_at)) { - throw new BadRequestHttpException( - 'This ISO cannot be deleted at this time: not completed.', - ); - } - - $this->connection->transaction(function () use ($node, $iso) { - if ($iso->is_successful) { - $this->repository->setNode($node)->deleteFile(ContentType::ISO, $iso->file_name); - } - - $iso->delete(); - }); - } -} diff --git a/app/Services/Mail/MailConfigurator.php b/app/Services/Mail/MailConfigurator.php new file mode 100644 index 00000000000..d9e2986b4e6 --- /dev/null +++ b/app/Services/Mail/MailConfigurator.php @@ -0,0 +1,171 @@ +notify()` + * untouched; this class only rewrites `config('mail.*')` early enough that the + * mail manager has not resolved a transport yet. Centralising it matters + * because the settings screen has to be able to build the *same* transport from + * an unsaved form to test it, and a second, subtly different mapping between + * "what we test" and "what we send with" would make the test button a liar. + */ +class MailConfigurator +{ + /** The throwaway mailer name a connection test is sent through. */ + public const TEST_MAILER = 'convoy-settings-test'; + + public function __construct(private MailSettings $settings) {} + + /** + * Whether anything can actually deliver. + * + * There is no environment tier for SMTP any more: the install migration imported whatever + * `MAIL_*` held, so the form is the only place SMTP comes from and a blank host means the + * panel has no relay. Reading the environment as a fallback here is exactly the second + * source of truth that was removed. + */ + public function isConfigured(): bool + { + return $this->settings->isConfigured() || $this->managedElsewhere(); + } + + /** + * Whether delivery is handled by a transport this screen does not own. + * + * ses, postmark, resend and mailgun are configured entirely through credentials there are no + * fields for here, so an install using one is configured — just not by this form. Saying + * otherwise would send an operator to fix an outage they do not have. + * + * `log` and `array` are excluded on purpose: they accept every message and deliver none, so + * counting them would report that mail works when the only thing receiving it is a file. + */ + private function managedElsewhere(): bool + { + $mailer = (string) config('mail.default'); + + return ! in_array($mailer, ['smtp', 'log', 'array', ''], true); + } + + /** + * Push the stored settings onto the runtime config. + * + * A no-op when no host is stored, which leaves whatever Laravel was already configured + * with — relevant only for the non-SMTP transports this screen does not manage. + */ + public function apply(): void + { + if (! $this->settings->isConfigured()) { + return; + } + + Config::set('mail.default', 'smtp'); + Config::set('mail.mailers.smtp', $this->transportConfig()); + Config::set('mail.from', [ + 'address' => $this->settings->from_address, + 'name' => $this->settings->from_name, + ]); + } + + /** + * Apply, then discard any mailer the manager already built. + * + * Only the settings screen needs this: everywhere else the config is in place before the + * first mailer is resolved, but saving happens mid-request, after something may already + * hold a mailer built from the previous credentials. + */ + public function applyAndPurge(): void + { + $this->apply(); + + Mail::purge('smtp'); + } + + /** + * The stored settings as a Laravel smtp mailer array. + * + * @return array + */ + public function transportConfig(): array + { + return $this->buildTransportConfig( + $this->settings->host, + $this->settings->port, + $this->settings->username, + $this->settings->password, + $this->settings->encryption, + ); + } + + /** + * @return array + */ + public function buildTransportConfig( + string $host, + int $port, + string $username, + string $password, + MailEncryption $encryption, + ): array { + return [ + 'transport' => 'smtp', + 'scheme' => $encryption->scheme(), + 'host' => $host, + 'port' => $port, + // Empty strings rather than nulls would make Symfony attempt an AUTH + // handshake against relays that allow unauthenticated submission. + 'username' => $username !== '' ? $username : null, + 'password' => $password !== '' ? $password : null, + 'timeout' => 10, + 'local_domain' => parse_url((string) config('app.url'), PHP_URL_HOST) ?: null, + ]; + } + + /** + * Send a test message through an ad-hoc mailer built from the given config, + * bypassing both the stored settings and the queue. + * + * Ad-hoc on purpose: the settings screen tests credentials the operator has + * typed but not yet saved, so this cannot read from storage. Sending it + * synchronously is equally deliberate — a queued test would report success + * the moment it was enqueued, which is precisely the failure mode (auth + * rejected on a worker, hours later, silently) that this screen exists to + * eliminate. + * + * @param array $transport + * + * @throws \Throwable the raw transport error, which is the useful part + */ + public function sendTest( + string $recipient, + array $transport, + string $fromAddress, + string $fromName, + MailEncryption $encryption, + ): void { + Config::set('mail.mailers.'.self::TEST_MAILER, $transport); + + try { + Mail::mailer(self::TEST_MAILER) + ->to($recipient) + ->send(new TestMailMessage( + $fromAddress, + $fromName, + $transport['host'], + $transport['port'], + $encryption, + )); + } finally { + // Never leave a transport holding the typed credentials on the manager. + Mail::purge(self::TEST_MAILER); + Config::set('mail.mailers.'.self::TEST_MAILER, null); + } + } +} diff --git a/app/Services/Mail/TestMailMessage.php b/app/Services/Mail/TestMailMessage.php new file mode 100644 index 00000000000..ba4f17b3219 --- /dev/null +++ b/app/Services/Mail/TestMailMessage.php @@ -0,0 +1,61 @@ +fromAddress, $this->fromName), + subject: config('app.name').' mail configuration test', + ); + } + + public function content(): Content + { + // A real view rather than a raw string so the test also exercises the + // rendering pipeline — a mail config that connects but cannot render is + // still a mail config that will not deliver. + // + // The settings are echoed back into the body because the useful answer + // is not "something arrived" but "*these* credentials are the ones that + // worked". An operator testing a host change against a stale saved + // password gets to see which of the two the relay accepted. + return new Content( + view: 'mail.test', + with: [ + 'host' => $this->host, + 'port' => (string) $this->port, + 'encryption' => $this->encryption->label(), + 'fromAddress' => $this->fromAddress, + ], + ); + } +} diff --git a/app/Services/Metrics/VictoriaMetrics.php b/app/Services/Metrics/VictoriaMetrics.php new file mode 100644 index 00000000000..b5548ea97f9 --- /dev/null +++ b/app/Services/Metrics/VictoriaMetrics.php @@ -0,0 +1,96 @@ +get('metrics.victoriametrics.url'); + $this->baseUrl = is_string($url) && $url !== '' ? rtrim($url, '/') : null; + } + + public function enabled(): bool + { + return $this->baseUrl !== null; + } + + /** + * Persist a batch of gauge samples at the current time via the Prometheus import endpoint. + * + * @param array $metrics metric name => value + */ + public function writeNow(array $metrics): void + { + if (! $this->enabled() || $metrics === []) { + return; + } + + $timestampMs = (int) (now()->getTimestamp() * 1000); + $body = ''; + foreach ($metrics as $name => $value) { + $body .= "{$name} {$value} {$timestampMs}\n"; + } + + try { + Http::timeout(5) + ->withBody($body, 'text/plain') + ->post("{$this->baseUrl}/api/v1/import/prometheus") + ->throw(); + } catch (Throwable $e) { + Log::warning('VictoriaMetrics write failed', ['error' => $e->getMessage()]); + } + } + + /** + * Range query. Returns each series' points keyed by metric name, oldest first. + * + * @return array> + */ + public function queryRange(string $query, string $start, string $end, string $step): array + { + if (! $this->enabled()) { + return []; + } + + try { + $response = Http::timeout(5)->get("{$this->baseUrl}/api/v1/query_range", [ + 'query' => $query, + 'start' => $start, + 'end' => $end, + 'step' => $step, + ]); + + $out = []; + foreach ($response->json('data.result', []) as $series) { + $name = $series['metric']['__name__'] ?? null; + if ($name === null) { + continue; + } + $out[$name] = array_map( + fn (array $point): array => [(int) $point[0], (float) $point[1]], + $series['values'] ?? [], + ); + } + + return $out; + } catch (Throwable $e) { + Log::warning('VictoriaMetrics query failed', ['error' => $e->getMessage()]); + + return []; + } + } +} diff --git a/app/Services/Nodes/ClusterIdentityService.php b/app/Services/Nodes/ClusterIdentityService.php new file mode 100644 index 00000000000..1ebb0199e52 --- /dev/null +++ b/app/Services/Nodes/ClusterIdentityService.php @@ -0,0 +1,273 @@ +clusterStatus->setNode($node)->getStatus(); + } catch (ConvoyRequestException|GuzzleRequestException|ConnectionException) { + return $node->cluster; + } + + return $status->clusterName === null + ? $this->resolveStandalone($node) + : $this->resolveClustered($node, $status->clusterName, $status->memberNames); + } + + private function resolveStandalone(Node $node): Cluster + { + $current = $node->cluster; + + if ($current !== null && $current->isStandalone()) { + // The label lingers when the singleton was minted by the upgrade + // migration from an old `cluster_name`; the host has now said + // plainly that it is standalone. + if ($current->name !== null || $current->member_names !== [$node->name]) { + $current->forceFill(['name' => null, 'member_names' => [$node->name]])->save(); + } + + return $current; + } + + return $this->rehome($node, Cluster::create([ + 'fingerprint' => null, + 'name' => null, + 'member_names' => [$node->name], + ])); + } + + /** + * @param array $memberNames + */ + private function resolveClustered(Node $node, string $clusterName, array $memberNames): ?Cluster + { + $current = $node->cluster; + + // Steady state: same cluster row, same label, members still overlap. + // No certificate fetch -- identity questions only get asked when + // something suggests the answer moved. + if ( + $current !== null + && ! $current->isStandalone() + && $current->name === $clusterName + && ! $this->isDisjoint($current->member_names, $memberNames) + ) { + $this->adoptReport($current, $clusterName, $memberNames); + + return $current; + } + + try { + $fingerprint = $this->certificates->setNode($node)->getClusterCaFingerprint(); + } catch (ConvoyRequestException|GuzzleRequestException|ConnectionException) { + $fingerprint = null; + } + + // Could not identify the cluster (lookup failed, or no CA row). The + // previous answer stands; a node never resolved stays unresolved until + // a poll can identify it. + if ($fingerprint === null) { + return $current; + } + + $cluster = Cluster::query()->firstOrCreate( + ['fingerprint' => $fingerprint], + ['name' => $clusterName, 'member_names' => $memberNames], + ); + + if (! $cluster->wasRecentlyCreated) { + $this->adoptReport($cluster, $clusterName, $memberNames); + } + + return $node->cluster_id === $cluster->id + ? $cluster + : $this->rehome($node, $cluster); + } + + /** + * Record what the poll reported on the cluster row -- unless the member + * set is disjoint from the stored one, which is the tripwire: either every + * member was renamed at once, or two clusters share a CA (a separated node + * re-clustered on the old certificate). Both deserve a human, so the row + * is flagged and the stored members stand as evidence. + */ + private function adoptReport(Cluster $cluster, string $clusterName, array $memberNames): void + { + if ($this->isDisjoint($cluster->member_names, $memberNames)) { + if ($cluster->flagged_at === null) { + $cluster->forceFill([ + 'flagged_at' => now(), + 'flag_reason' => sprintf( + 'Reported members [%s] share nothing with recorded members [%s].', + implode(', ', $memberNames), + implode(', ', $cluster->member_names ?? []), + ), + ])->save(); + } + + return; + } + + if ($cluster->name !== $clusterName || $cluster->member_names !== $memberNames) { + $cluster->forceFill(['name' => $clusterName, 'member_names' => $memberNames])->save(); + } + } + + /** + * @param ?array $stored + * @param array $reported + */ + private function isDisjoint(?array $stored, array $reported): bool + { + if ($stored === null || $stored === [] || $reported === []) { + return false; + } + + return array_intersect($stored, $reported) === []; + } + + /** + * Move the node into its newly resolved scope. + * + * A singleton's storages come along and merge by name -- the node was the + * scope, so its registrations are its own to carry (this is what folds + * v4's per-node rows into one definition per cluster on the first poll + * after upgrading). Leaving a *cluster* carries nothing: those pools + * belong to the cluster, so the node's links to them are severed and its + * new scope starts empty. An emptied singleton row is deleted. + */ + private function rehome(Node $node, Cluster $cluster): Cluster + { + $previous = $node->cluster; + + $this->connection->transaction(function () use ($node, $cluster, $previous) { + $node->forceFill(['cluster_id' => $cluster->id])->save(); + + if ($previous === null) { + return; + } + + if ($previous->isStandalone()) { + $previous->storages() + ->get() + ->each(fn (Storage $storage) => $this->mergeIntoScope($storage, $cluster)); + } else { + StorageToNode::query() + ->where('node_id', $node->id) + ->whereIn('storage_id', $previous->storages()->select('id')) + ->delete(); + } + + if ( + $previous->isStandalone() + && ! $previous->nodes()->exists() + && ! $previous->storages()->exists() + ) { + $previous->delete(); + } + }); + + return $cluster; + } + + /** + * Move one storage definition into a scope, folding it into the scope's + * same-named definition when one exists: everything referencing the + * arriving row is re-pointed at the established one, links move without + * ever duplicating a (storage, node) pair, and the arriving row is + * deleted. + */ + private function mergeIntoScope(Storage $arriving, Cluster $cluster): void + { + /** @var ?Storage $established */ + $established = $cluster->storages()->where('name', $arriving->name)->first(); + + if ($established === null) { + $arriving->forceFill(['cluster_id' => $cluster->id])->save(); + + return; + } + + // ISOs are deliberately absent: a library entry names no storage any + // more, so there is nothing to re-point when two storages turn out to + // be the same one. + foreach ([Server::class, Backup::class, ServerDisk::class] as $model) { + $model::query() + ->where('storage_id', $arriving->id) + ->update(['storage_id' => $established->id]); + } + + $establishedNodeIds = StorageToNode::query() + ->where('storage_id', $established->id) + ->pluck('node_id'); + + StorageToNode::query() + ->where('storage_id', $arriving->id) + ->whereIn('node_id', $establishedNodeIds) + ->delete(); + + StorageToNode::query() + ->where('storage_id', $arriving->id) + ->update(['storage_id' => $established->id]); + + $arriving->delete(); + } +} diff --git a/app/Services/Nodes/GuestStateCache.php b/app/Services/Nodes/GuestStateCache.php new file mode 100644 index 00000000000..bf9d0dea786 --- /dev/null +++ b/app/Services/Nodes/GuestStateCache.php @@ -0,0 +1,218 @@ +id); + } + + public static function keyForNodeId(int $nodeId): string + { + return "node:{$nodeId}:vm-states"; + } + + public static function guestKeyForServerId(int $serverId): string + { + return "server:{$serverId}:power-state"; + } + + /** + * Record a whole node's guest map, as of now. + * + * @param array $states vmid => PVE status string + */ + public function put(Node $node, array $states): void + { + Cache::put(self::key($node), [ + 'observed_at' => $this->nowMs(), + 'states' => $states, + ], now()->addMinutes(self::TTL_MINUTES)); + } + + /** + * Record one guest's state, as of now, from a live read of that guest. + * + * Deliberately a key of its own rather than a patch into the node map. + * Rewriting the map would reset its expiry, and that expiry is load-bearing + * -- it is the only thing that says "nobody has polled this node lately". + * A power action must not be able to make a stale map look freshly polled. + */ + public function observe(Server $server, PowerState $state): void + { + Cache::put(self::guestKeyForServerId($server->id), [ + 'observed_at' => $this->nowMs(), + 'state' => $state->value, + ], now()->addMinutes(self::TTL_MINUTES)); + } + + /** + * @return array|null null when the node has not been polled + * recently enough to say + */ + public function for(Node $node): ?array + { + return $this->forNodeId($node->id); + } + + /** + * @return array|null + */ + public function forNodeId(int $nodeId): ?array + { + return $this->snapshotForNodeId($nodeId)['states'] ?? null; + } + + public function forget(Node $node): void + { + Cache::forget(self::key($node)); + } + + /** + * The remembered state of one guest, or null for "we cannot say". + * + * Null covers both a node nobody has polled and a guest PVE did not + * mention. The second is not the same as `stopped`: a guest missing from + * `/cluster/resources` has usually been removed outside Convoy, and + * answering `stopped` would invite someone to press Start on it. + * + * Where a single-guest observation and the node map disagree, the more + * recently observed one wins -- in *either* direction. Preferring the + * single-guest write unconditionally would be the obvious shortcut and is + * wrong: a guest stopped outside Convoy after someone last watched it would + * keep reading `running` off an observation the poller has since + * superseded. Whichever fact was recorded later is the one that describes + * the present. + */ + public function stateFor(Server $server): ?PowerState + { + // Keyed off `node_id` rather than the `node` relation on purpose: a + // server list resolves this once per row, and touching the relation + // would load a node per row to build a key it already has. The + // observation timestamps live in the cached values for the same reason + // -- comparing against `nodes.status_checked_at` would reintroduce + // exactly that per-row load. + $snapshot = $this->snapshotForNodeId($server->node_id); + $observation = $this->observationFor($server); + + if ($observation === null) { + return $this->stateFromSnapshot($snapshot, $server->vmid); + } + + // Ties go to the single-guest read: it looked at this one guest + // directly, where the poll answered for the whole node at once. + if ($snapshot === null || $observation['observed_at'] >= $snapshot['observed_at']) { + return PowerState::tryFrom($observation['state']); + } + + return $this->stateFromSnapshot($snapshot, $server->vmid); + } + + /** + * @param array{observed_at: int, states: array}|null $snapshot + */ + private function stateFromSnapshot(?array $snapshot, int $vmid): ?PowerState + { + if ($snapshot === null || ! array_key_exists($vmid, $snapshot['states'])) { + return null; + } + + return PowerState::tryFrom($snapshot['states'][$vmid]); + } + + /** + * @return array{observed_at: int, states: array}|null + */ + private function snapshotForNodeId(int $nodeId): ?array + { + $record = Cache::get(self::keyForNodeId($nodeId)); + + if (! is_array($record)) { + return null; + } + + // A bare vmid => status map is what an older release wrote, with no + // observation time attached. Dated to the epoch so that any timestamped + // observation outranks it, rather than guessing an age for it; the + // ambiguity lasts only the minute it takes the next poll to overwrite. + if (! array_key_exists('states', $record)) { + return ['observed_at' => 0, 'states' => $record]; + } + + return ['observed_at' => (int) $record['observed_at'], 'states' => $record['states']]; + } + + /** + * @return array{observed_at: int, state: string}|null + */ + private function observationFor(Server $server): ?array + { + $record = Cache::get(self::guestKeyForServerId($server->id)); + + if (! is_array($record) || ! isset($record['state'], $record['observed_at'])) { + return null; + } + + return ['observed_at' => (int) $record['observed_at'], 'state' => (string) $record['state']]; + } + + /** + * Milliseconds, not seconds: the poll and a live read can land inside the + * same second, and at second resolution the tie-break would decide which + * fact wins far more often than it should. + */ + private function nowMs(): int + { + return now()->getTimestampMs(); + } +} diff --git a/app/Services/Nodes/LiveStorageService.php b/app/Services/Nodes/LiveStorageService.php new file mode 100644 index 00000000000..cfd3e00871a --- /dev/null +++ b/app/Services/Nodes/LiveStorageService.php @@ -0,0 +1,64 @@ + + */ + public function forNode(Node $node): Collection + { + return Cache::remember("node:{$node->id}:live-storages", now()->addSeconds(15), function () use ($node) { + try { + return collect($this->client->setNode($node)->getStorages()->all()) + ->keyBy(fn (StorageData $storage) => $storage->name); + } catch (RequestException|ConnectionException) { + return collect(); + } + }); + } + + public function get(Node $node, string $name): ?StorageData + { + return $this->forNode($node)->get($name); + } + + /** + * Bytes Convoy may actually allocate on this storage right now: + * live physical free − the operator's reserve buffer. Returns null when the + * node/storage is unreachable, so callers fail open rather than block. + */ + public function freeForConvoy(Node $node, Storage $storage): ?int + { + $live = $this->get($node, $storage->name); + if ($live === null) { + return null; + } + + return max(0, $live->free - (int) ($storage->reserved_bytes ?? 0)); + } +} diff --git a/app/Services/Nodes/NodeConnectionTestService.php b/app/Services/Nodes/NodeConnectionTestService.php new file mode 100644 index 00000000000..bd90aa5d779 --- /dev/null +++ b/app/Services/Nodes/NodeConnectionTestService.php @@ -0,0 +1,37 @@ +client + ->setNode($node) + ->getStatus(); + } catch (ConvoyRequestException|GuzzleRequestException|ConnectionException $exception) { + $message = $exception->getMessage(); + $errorType = Error::classify($message); + } + + return new ConnectionResultData( + success : isset($status), + errorMessage: $message ?? null, + errorCode : $errorType ?? null, + data : $status ?? null, + ); + } +} diff --git a/app/Services/Nodes/NodeResourceSnapshotCache.php b/app/Services/Nodes/NodeResourceSnapshotCache.php new file mode 100644 index 00000000000..e17215ccffa --- /dev/null +++ b/app/Services/Nodes/NodeResourceSnapshotCache.php @@ -0,0 +1,135 @@ +id}:resource-snapshot:v2"; + } + + /** + * @param Collection $storages this node's datastores; empty is a + * legitimate answer, not a failure + */ + public function put(Node $node, NodeResourceData $resource, Collection $storages = new Collection): void + { + $datastores = $this->datastores($storages); + $readable = collect($datastores->items()) + ->filter(fn (NodeDatastoreUsageData $datastore) => $datastore->online); + + Cache::put( + self::key($node), + new NodeResourceSnapshotData( + cpu: new NodeProcessorUsageData( + count: $resource->cpuCount, + percent: $this->percentage($resource->cpuUsed * 100, 100), + ), + memory: new ResourceUsageData( + used: $resource->memoryUsed, + total: $resource->memoryTotal, + percent: $this->percentage($resource->memoryUsed, $resource->memoryTotal), + ), + disk: new ResourceUsageData( + used: $resource->diskUsed, + total: $resource->diskTotal, + percent: $this->percentage($resource->diskUsed, $resource->diskTotal), + ), + uptimeInSeconds: $resource->uptimeInSeconds, + observedAt: CarbonImmutable::now(), + storage: $this->aggregate($readable), + datastoreCount: $datastores->count(), + unreadableDatastores: $datastores->count() - $readable->count(), + datastores: $datastores, + ), + now()->addMinutes(Node::STATUS_TTL_MINUTES), + ); + } + + /** + * Every readable datastore summed into one used/total pair. + * + * A sum of raw bytes, not a mean of percentages: averaging the percentages + * would let a full 10 GiB scratch store weigh as heavily as a half-empty + * 20 TiB array, which is exactly backwards. + * + * @param Collection $readable + */ + private function aggregate(Collection $readable): ResourceUsageData + { + $used = (int) $readable->sum(fn (NodeDatastoreUsageData $datastore) => $datastore->usage->used); + $total = (int) $readable->sum(fn (NodeDatastoreUsageData $datastore) => $datastore->usage->total); + + return new ResourceUsageData( + used: $used, + total: $total, + percent: $this->percentage($used, $total), + ); + } + + /** + * @param Collection $storages + * @return DataCollection + */ + private function datastores(Collection $storages): DataCollection + { + $datastores = $storages + ->map(fn (StorageResourceData $storage) => new NodeDatastoreUsageData( + name: $storage->name, + usage: new ResourceUsageData( + used: $storage->used, + total: $storage->total, + percent: $this->percentage($storage->used, $storage->total), + ), + // PVE says `available` when it could actually read the store. + // Anything else (typically `unknown`) means the figures beside + // it are not to be trusted. + online: $storage->status === 'available', + shared: $storage->shared, + )) + // Fullest first: on a card that shows every store, the one about to + // run out is the only one worth reading at a glance. + ->sortByDesc(fn (NodeDatastoreUsageData $datastore) => $datastore->usage->percent) + ->values() + ->all(); + + return NodeDatastoreUsageData::collect($datastores, DataCollection::class); + } + + public function for(Node $node): ?NodeResourceSnapshotData + { + return Cache::get(self::key($node)); + } + + private function percentage(float|int $used, int $total): float + { + if ($total <= 0) { + return 0; + } + + return round(min(max(($used / $total) * 100, 0), 100), 2); + } +} diff --git a/app/Services/Nodes/NodeStatusPollService.php b/app/Services/Nodes/NodeStatusPollService.php new file mode 100644 index 00000000000..c22e8104a81 --- /dev/null +++ b/app/Services/Nodes/NodeStatusPollService.php @@ -0,0 +1,168 @@ +client->setNode($node)->getResourceSnapshot(); + } catch (ConvoyRequestException|GuzzleRequestException|ConnectionException $e) { + // The guest map is deliberately left to expire on its own rather + // than being forgotten here. Until it lapses it is still the last + // thing we actually observed, and a single failed poll is not + // evidence that anything changed state. + return $this->markUnreachable($node, $e->getMessage()); + } + + $this->guestStates->put($node, $this->mapGuestStates($node, $resources->servers)); + + $storages = $this->storagesFor($node, $resources->storages); + + $resource = $this->findNodeResource($node, $resources); + if ($resource !== null) { + $this->resourceSnapshots->put($node, $resource, $storages); + } + + // Which scope this node is in, resolved (and, when the host says it + // moved, re-homed) before anything storage-shaped is written: both + // steps below read the node's scope back out of the database. + $cluster = $this->clusterIdentity->resolve($node); + + // Each guest row names the node it is actually on right now -- the + // authoritative answer after an HA recovery or migration, which no + // task log reliably records. Reconcile `servers.node_id` against it + // while the snapshot is in hand. + $this->serverPlacement->reconcile($cluster, $resources->servers); + + // What PVE says about the storages Convoy has registered, recorded next + // to what the operator declared so the two can be compared. + $this->storageDiscovery->handle($node, $storages); + + $status = $this->markOnline($node); + + // The response describes the whole cluster's storage layout, not just + // this node's, so one poll is enough to keep every link matched to + // where Proxmox says each pool is actually available. + $this->storageLinkSync->handle($node, $cluster, $resources); + + return $status; + } + + /** + * This node's datastores, from the response we already have. + * + * Same cluster trap as the guest map: `/cluster/resources` answers for every + * member, and a shared store is reported once per node that mounts it. Without + * the filter one host's datastores would be attributed to another. + * + * @param Collection $storages + * @return Collection + */ + private function storagesFor(Node $node, Collection $storages): Collection + { + return $storages + ->filter(fn (StorageResourceData $storage) => $storage->nodeName === $node->name) + ->values(); + } + + private function findNodeResource(Node $node, ClusterResourceSnapshot $resources): ?NodeResourceData + { + return $resources->nodes->first( + fn (NodeResourceData $resource) => $resource->nodeName === $node->name, + ); + } + + /** + * @param Collection $guests + * @return array vmid => PVE status string + */ + private function mapGuestStates(Node $node, Collection $guests): array + { + return $guests + // On a real cluster this endpoint answers for every member, not + // just the host we asked. Without this filter another node's guests + // would be recorded against this one -- and vmids are only unique + // per cluster, so the collision is silent. + ->filter(fn (ServerResourceData $guest) => $guest->nodeName === $node->name) + ->mapWithKeys(fn (ServerResourceData $guest) => [$guest->vmid => $guest->status]) + ->all(); + } + + private function markOnline(Node $node): NodeStatus + { + $node->forceFill([ + 'status' => NodeStatus::ONLINE, + 'status_code' => null, + 'status_message' => null, + 'last_seen_at' => now(), + 'status_checked_at' => now(), + 'consecutive_failures' => 0, + ])->save(); + + return NodeStatus::ONLINE; + } + + private function markUnreachable(Node $node, string $message): NodeStatus + { + $node->forceFill([ + 'status' => NodeStatus::UNREACHABLE, + // Classified through the same vocabulary the connection test and + // NodeUnreachableException use, so "why is this node unhappy" reads + // identically wherever it surfaces. + 'status_code' => ConnectionErrorCode::classify($message), + 'status_message' => $message, + 'status_checked_at' => now(), + // last_seen_at deliberately untouched: it records the last time the + // node actually answered, which is what staleness is measured from. + 'consecutive_failures' => $node->consecutive_failures + 1, + ])->save(); + + return NodeStatus::UNREACHABLE; + } +} diff --git a/app/Services/Nodes/ServerPlacementService.php b/app/Services/Nodes/ServerPlacementService.php new file mode 100644 index 00000000000..e3db6bdc3b8 --- /dev/null +++ b/app/Services/Nodes/ServerPlacementService.php @@ -0,0 +1,255 @@ + $guests every guest in the + * snapshot, unfiltered -- each row carries the node it is actually on + */ + public function reconcile(?Cluster $cluster, Collection $guests): void + { + // Standalone scopes have nowhere for a guest to move to, an unresolved + // node has no scope to compare within, and a flagged cluster's identity + // is itself in doubt -- re-homing on top of that would compound a guess. + if ($cluster === null || $cluster->isStandalone() || $cluster->flagged_at !== null) { + return; + } + + // Every member's poll sees the whole cluster, so N nodes would run + // this N times a minute; the first poll of the cycle does the work. + $lock = Cache::lock("cluster:{$cluster->id}:server-placement", 55); + + if (! $lock->get()) { + return; + } + + try { + $this->reconcileScope($cluster, $guests); + } finally { + $lock->release(); + } + } + + /** + * @param Collection $guests + */ + private function reconcileScope(Cluster $cluster, Collection $guests): void + { + $reported = $guests + ->filter(fn (ServerResourceData $guest) => ! $guest->isTemplate && $guest->nodeName !== null) + ->keyBy(fn (ServerResourceData $guest) => $guest->vmid); + + $servers = Server::query() + ->whereHas('node', fn (Builder $query) => $query->where('cluster_id', $cluster->id)) + ->with(['node', 'networkInterface']) + ->get(); + + $vmidCounts = $servers->countBy('vmid'); + + foreach ($servers as $server) { + $guest = $reported->get($server->vmid); + + // A guest missing from the snapshot entirely is the existing + // "removed outside Convoy" story (see GuestStateCache), not a + // placement question; a guest on the recorded node is in place. + if ($guest === null || $guest->nodeName === $server->node->name) { + continue; + } + + if ($vmidCounts[$server->vmid] > 1) { + $this->flag($server, sprintf( + 'VMID %d is held by more than one server in this cluster; cannot tell which one moved to %s.', + $server->vmid, + $guest->nodeName, + )); + + continue; + } + + // Mid-migration the guest is transiently visible on the target; + // the next poll sees where it actually ended up. + if ($guest->lockStatus === ProxmoxLock::MIGRATE) { + continue; + } + + $target = Node::query() + ->where('cluster_id', $cluster->id) + ->where('name', $guest->nodeName) + ->first(); + + if ($target === null) { + $this->flag($server, sprintf( + 'Guest %d moved to cluster member "%s", which is not registered in Convoy.', + $server->vmid, + $guest->nodeName, + )); + + continue; + } + + $confirmed = $this->confirmIdentity($server, $target); + + // null: the target could not be asked right now. Not evidence of + // anything -- leave the row alone and let a later poll decide. + if ($confirmed === null) { + continue; + } + + if (! $confirmed) { + $this->flag($server, sprintf( + 'Guest %d on "%s" does not carry this server\'s SMBIOS UUID; refusing to re-home.', + $server->vmid, + $guest->nodeName, + )); + + continue; + } + + $this->rehome($server, $target); + } + } + + /** + * Whether the guest on the target node is the same machine this row + * describes. True when the stamped SMBIOS UUID matches, or when the server + * predates stamping (the (cluster, vmid) pair is then the identity, which + * PVE itself enforces unique). Null when the config cannot be fetched. + */ + private function confirmIdentity(Server $server, Node $target): ?bool + { + if ($server->smbios_uuid === null) { + return true; + } + + try { + $config = $this->configClient->setServer($server)->setNode($target)->getRawConfig(); + } catch (ConvoyRequestException|GuzzleRequestException|ConnectionException) { + return null; + } + + return $this->smbiosUuid($config['smbios1'] ?? null) === Str::lower($server->smbios_uuid); + } + + private function smbiosUuid(?string $smbios): ?string + { + if ($smbios === null) { + return null; + } + + $uuid = Str::match('/(?:^|,)uuid=([0-9a-fA-F-]{36})/', $smbios); + + return $uuid === '' ? null : Str::lower($uuid); + } + + /** + * Point the row at where the guest actually is. The interface link moves + * with it by bridge name -- or is cleared and the server flagged when the + * target has no such bridge, because a network sync through a bridge the + * node doesn't have is how a survived failover turns into an outage. + */ + private function rehome(Server $server, Node $target): void + { + $previous = $server->node; + $bridge = $server->networkInterface?->name; + + $interface = $bridge === null ? null : NetworkInterface::query() + ->where('node_id', $target->id) + ->where('name', $bridge) + ->first(); + + $this->connection->transaction(function () use ($server, $target, $previous, $interface) { + $server->forceFill([ + 'node_id' => $target->id, + 'network_interface_id' => $interface?->id, + // A clean re-home resolves whatever placement anomaly was + // flagged before (e.g. the target node has since been + // registered); a missing bridge immediately re-flags below. + 'flagged_at' => null, + 'flag_reason' => null, + ])->save(); + + $this->audit->record( + AuditEvent::ADMIN_SERVER_REHOMED, + $server, + ['from' => $previous->name, 'to' => $target->name, 'vmid' => $server->vmid], + SystemActor::instance(), + ); + }); + + if ($bridge !== null && $interface === null) { + $this->flag($server, sprintf( + 'Re-homed to "%s", but it has no bridge named "%s"; the interface link was cleared and network sync is blocked until an operator resolves it.', + $target->name, + $bridge, + )); + } + } + + /** + * Record why this row was left alone. First observation wins -- the same + * anomaly is re-observed every poll, and overwriting the timestamp each + * minute would hide how long it has been standing. + */ + private function flag(Server $server, string $reason): void + { + if ($server->flagged_at !== null) { + return; + } + + $server->forceFill(['flagged_at' => now(), 'flag_reason' => $reason])->save(); + } +} diff --git a/app/Services/Nodes/ServerRateLimitsSyncService.php b/app/Services/Nodes/ServerRateLimitsSyncService.php index 86d9a998f79..666837d97f5 100644 --- a/app/Services/Nodes/ServerRateLimitsSyncService.php +++ b/app/Services/Nodes/ServerRateLimitsSyncService.php @@ -1,32 +1,56 @@ enforce the persistent per-server speed cap (or unlimited), + * and ensure the NIC is connected. + * - Over quota -> apply the resolved overage penalty, which always wins: + * throttle to the penalty rate, or disconnect the NIC. + * + * Called per-server by {@see SyncServerRateLimitJob}; failures + * propagate so the job (not this service) owns retry/isolation. + * + * See docs/bandwidth-rate-limiting-plan.md §3. + */ class ServerRateLimitsSyncService { - public function __construct(private NetworkService $service) - { - } + public function __construct( + private ServerNetworkBandwidthService $service, + private OveragePenaltyResolver $resolver, + ) {} - public function handle(Node $node) + /** + * @throws RequestException + * @throws ConfigModifiedException + */ + public function sync(Server $server): void { - $servers = $node->servers; - - $servers->each(function (Server $server) { - try { - if ($server->bandwidth_limit !== null && $server->bandwidth_usage >= $server->bandwidth_limit) { - $this->service->updateRateLimit($server, 1); - } else { - $this->service->updateRateLimit($server); - } - } catch (ProxmoxConnectionException $e) { - // do nothing - } - }); + if (! $server->isOverBandwidthQuota()) { + // Under quota: enforce the speed cap and make sure we're connected. + $this->service->apply($server, $server->speed_limit, linkDown: false); + + return; + } + + $penalty = $this->resolver->for($server); + + if ($penalty->isDisconnect()) { + $this->service->apply($server, $server->speed_limit, linkDown: true); + + return; + } + + // Throttle: the penalty rate wins over the speed cap. + $this->service->apply($server, $penalty->rate ?? $server->speed_limit, linkDown: false); } } diff --git a/app/Services/Nodes/ServerUsagesSyncService.php b/app/Services/Nodes/ServerUsagesSyncService.php index 188291fb511..143ca941474 100644 --- a/app/Services/Nodes/ServerUsagesSyncService.php +++ b/app/Services/Nodes/ServerUsagesSyncService.php @@ -1,37 +1,41 @@ servers; $servers->each(function (Server $server) { try { - $metrics = $this->repository->setServer($server)->getMetrics(MetricTimeframe::HOUR); + $timepoints = $this->client->setServer($server)->getStatistics( + StatisticTimeRange::HOUR_AGO, + ); $bandwidth = $server->bandwidth_usage; - $endingDate = $server->hydrated_at ? Carbon::parse($server->hydrated_at) : Carbon::now()->firstOfMonth(); + $endingDate = $server->hydrated_at ? Carbon::parse( + $server->hydrated_at, + ) : Carbon::now()->firstOfMonth(); - foreach ($metrics as $metric) { - if (Carbon::createFromTimestamp($metric['time'])->gt($endingDate)) { + foreach ($timepoints as $timepoint) { + /* @var ServerTimepointData $timepoint */ + if ($timepoint->timestamp->gt($endingDate)) { // we multiply it by 60 seconds because each metric is // recorded every 1 minute but the values like netin and // netout are in bytes/sec - $bandwidth += (int) $metric['netin'] * 60 + (int) $metric['netout'] * 60; + $bandwidth += $timepoint->network->in * 60 + $timepoint->network->out * 60; } } @@ -41,7 +45,7 @@ public function handle(Node $node) 'hydrated_at' => now(), ]); } - } catch (ProxmoxConnectionException $e) { + } catch (RequestException $e) { // do nothing } }); diff --git a/app/Services/Nodes/StorageDiscoveryService.php b/app/Services/Nodes/StorageDiscoveryService.php new file mode 100644 index 00000000000..2be3e8c764d --- /dev/null +++ b/app/Services/Nodes/StorageDiscoveryService.php @@ -0,0 +1,90 @@ + $storages this node's rows, already filtered + */ + public function handle(Node $node, Collection $storages): void + { + if ($storages->isEmpty()) { + return; + } + + $reported = $storages->keyBy(fn (StorageResourceData $storage) => $storage->name); + + // Only the storages Convoy knows about. A PVE storage nobody registered + // is not an error and not ours to create -- deciding which stores Convoy + // may use is the operator's call, and importing silently would make it + // Convoy's. + $node->storages()->get()->each(function (Storage $storage) use ($node, $reported) { + $live = $reported->get($storage->name); + + // Registered here but absent from PVE's report: leave the last known + // values alone rather than blanking them. One poll that did not + // mention a store is not evidence the store is gone, and wiping the + // figures would turn a rename into "capacity unknown" everywhere. + // (Whether the *link* should survive is the sync's question, not + // this one -- and it only severs links this service once confirmed.) + if ($live === null) { + return; + } + + $storage->forceFill([ + 'pve_type' => $live->type, + 'pve_shared' => $live->shared, + // The list itself is the record: what a storage can hold is read + // off it on demand rather than projected into columns that could + // then disagree with it. + // + // Left alone when the report carried no list at all. That is a + // report that did not say, not a storage that holds nothing, and + // overwriting with null would take the store out of every + // allocation the panel offers until the next poll that does say. + ...$live->content !== null ? ['pve_content' => $live->content] : [], + ])->save(); + + // `available` is PVE saying it actually read the store. Anything + // else means the numbers beside it are not worth recording, so + // the previous ones stand. + if ($live->status === 'available') { + StorageToNode::query() + ->where('storage_id', $storage->id) + ->where('node_id', $node->id) + ->update([ + 'discovered_total' => $live->total, + 'discovered_used' => $live->used, + 'discovered_at' => now(), + ]); + } + }); + } +} diff --git a/app/Services/Nodes/StorageLinkSyncService.php b/app/Services/Nodes/StorageLinkSyncService.php new file mode 100644 index 00000000000..4275177c3b4 --- /dev/null +++ b/app/Services/Nodes/StorageLinkSyncService.php @@ -0,0 +1,147 @@ + $peers */ + $peers = $cluster->nodes()->get()->keyBy('name'); + + // Only pools Convoy has been told to manage. Registering a storage is + // the operator's decision -- this answers "where is it", never "should + // we use it". + $registered = Storage::query() + ->where('cluster_id', $cluster->id) + ->with('nodes') + ->get() + ->keyBy('name'); + + if ($registered->isEmpty()) { + return; + } + + $this->attachShared($resources, $peers, $registered); + $this->pruneVanished($resources, $peers, $registered); + } + + /** + * @param Collection $peers + * @param Collection $registered + */ + private function attachShared(ClusterResourceSnapshot $resources, Collection $peers, Collection $registered): void + { + foreach ($resources->storages as $row) { + if (! $row->shared) { + continue; + } + + $node = $peers->get($row->nodeName); + $storage = $registered->get($row->name); + + // A host Convoy does not manage, or a pool nobody registered. + if ($node === null || $storage === null) { + continue; + } + + if ($storage->nodes->contains('id', $node->id)) { + continue; + } + + try { + StorageToNode::create([ + 'storage_id' => $storage->id, + 'node_id' => $node->id, + ]); + } catch (UniqueConstraintViolationException) { + // Two members polled in the same instant drew the same link; + // the row exists, which is all this wanted. + } + + // Keep the in-memory copy honest so a storage reported twice in one + // response is not inserted twice. + $storage->nodes->push($node); + } + } + + /** + * @param Collection $peers + * @param Collection $registered + */ + private function pruneVanished(ClusterResourceSnapshot $resources, Collection $peers, Collection $registered): void + { + // The response vouches only for members it lists as online: a member + // that is down is absent, not detached, and severing its links would + // turn an outage into a configuration change. + $vouchedFor = $resources->nodes + ->filter(fn (NodeResourceData $node) => $node->status === 'online') + ->pluck('nodeName') + ->flip(); + + $reportedPairs = $resources->storages + ->mapWithKeys(fn (StorageResourceData $row) => ["{$row->nodeName}|{$row->name}" => true]); + + foreach ($registered as $storage) { + foreach ($storage->nodes as $node) { + // Same name in another scope (possible mid-upgrade, while + // members are still converging one by one) is not this node. + $peer = $peers->get($node->name); + + if ( + $peer === null + || $peer->id !== $node->id + || ! isset($vouchedFor[$node->name]) + || isset($reportedPairs["{$node->name}|{$storage->name}"]) + || $node->pivot->discovered_at === null + ) { + continue; + } + + StorageToNode::query() + ->where('storage_id', $storage->id) + ->where('node_id', $node->id) + ->delete(); + } + } + } +} diff --git a/app/Services/Nodes/UserPruneService.php b/app/Services/Nodes/UserPruneService.php index 9252b9f231e..7fe669e825c 100644 --- a/app/Services/Nodes/UserPruneService.php +++ b/app/Services/Nodes/UserPruneService.php @@ -1,27 +1,25 @@ repository->setNode($node)->getUsers(); + $users = $this->client->setNode($node)->getUsers(); $users = $users->filter(function (UserData $user) { - return str_starts_with($user->username, 'convoy-') && $user->expires_at?->isPast(); + return str_starts_with($user->username, 'convoy-') && $user->expiresAt?->isPast(); }); $users->each(function (UserData $user) { - $this->repository->deleteUser($user->username, $user->realm_type); + $this->client->deleteUser($user->username, $user->realmType); }); } } diff --git a/app/Services/Proxmox/Cluster/ProxmoxClusterStatusClient.php b/app/Services/Proxmox/Cluster/ProxmoxClusterStatusClient.php new file mode 100644 index 00000000000..586346b6bb7 --- /dev/null +++ b/app/Services/Proxmox/Cluster/ProxmoxClusterStatusClient.php @@ -0,0 +1,50 @@ +getHttpClient() + ->get('/api2/json/cluster/status') + ->json(); + + $clusterName = null; + $memberNames = []; + + foreach ($this->getData($response) as $row) { + match (Arr::get($row, 'type')) { + 'cluster' => $clusterName = Arr::get($row, 'name'), + 'node' => $memberNames[] = (string) Arr::get($row, 'name'), + default => null, + }; + } + + return new ClusterStatusData($clusterName, $memberNames); + } +} diff --git a/app/Services/Proxmox/Cluster/ProxmoxResourceClient.php b/app/Services/Proxmox/Cluster/ProxmoxResourceClient.php new file mode 100644 index 00000000000..a9280428624 --- /dev/null +++ b/app/Services/Proxmox/Cluster/ProxmoxResourceClient.php @@ -0,0 +1,73 @@ + + * + * @throws RequestException + * @throws ConnectionException + */ + public function getResources(): Collection + { + $servers = array_filter($this->fetchResources(), function (array $resource) { + return Arr::get($resource, 'type') === 'qemu'; + }); + + return ServerResourceData::collect($servers, Collection::class); + } + + /** + * Decode the host and guest rows from one request for the scheduled poller. + * + * @throws RequestException + * @throws ConnectionException + */ + public function getResourceSnapshot(): ClusterResourceSnapshot + { + $resources = $this->fetchResources(); + + $nodes = array_filter( + $resources, + fn (array $resource) => Arr::get($resource, 'type') === 'node', + ); + $servers = array_filter( + $resources, + fn (array $resource) => Arr::get($resource, 'type') === 'qemu', + ); + $storages = array_filter( + $resources, + fn (array $resource) => Arr::get($resource, 'type') === 'storage', + ); + + return new ClusterResourceSnapshot( + nodes: NodeResourceData::collect($nodes, Collection::class), + servers: ServerResourceData::collect($servers, Collection::class), + storages: StorageResourceData::collect($storages, Collection::class), + ); + } + + /** @return array> */ + private function fetchResources(): array + { + $response = $this->getHttpClient() + ->get('/api2/json/cluster/resources') + ->json(); + + return $this->getData($response); + } +} diff --git a/app/Services/Proxmox/Node/ProxmoxAccessClient.php b/app/Services/Proxmox/Node/ProxmoxAccessClient.php new file mode 100644 index 00000000000..c440d128ff5 --- /dev/null +++ b/app/Services/Proxmox/Node/ProxmoxAccessClient.php @@ -0,0 +1,86 @@ +getHttpClient() + ->get('/api2/json/access/users') + ->json(); + + $users = array_map(fn ($user) => UserData::fromRaw($user), $this->getData($response)); + + return UserData::collect($users, DataCollection::class); + } + + public function createUser(CreateUserData $data): CreateUserData + { + $payload = [ + 'enable' => $data->enabled, + 'userid' => ($data->username ?? 'convoy-'.Str::random(53)).'@'.$data->realmType->value, + 'password' => $data->password ?? Str::random(64), + 'expire' => $data->expiresAt->timestamp ?? false, + ]; + + $this->getHttpClient() + ->post('/api2/json/access/users', $payload) + ->json(); + + return CreateUserData::from([ + 'username' => explode('@', $payload['userid'])[0], + 'realmType' => $data->realmType, + 'password' => $payload['password'], + 'enabled' => $payload['enable'], + 'expiresAt' => $data->expiresAt, + ]); + } + + public function deleteUser(string $id, RealmType $realmType) + { + $response = $this->getHttpClient() + ->withUrlParameters([ + 'user' => $id.'@'.$realmType->value, + ]) + ->delete('/api2/json/access/users/{user}') + ->json(); + + return $this->getData($response); + } + + public function createRole(string $name, string $privileges) + { + $payload = [ + 'roleid' => $name, + 'privs' => $privileges, + ]; + + $response = $this->getHttpClient() + ->post('/api2/json/access/roles', $payload) + ->json(); + + return $this->getData($response); + } + + public function createUserCredentials(RealmType $realmType, string $userid, string $password): UserCredentialsData + { + $response = $this->getHttpClient(shouldAuthorize: false) + ->post('/api2/json/access/ticket', [ + 'username' => $userid, + 'password' => $password, + 'realm' => $realmType->value, + ]) + ->json(); + + return UserCredentialsData::fromRaw($this->getData($response)); + } +} diff --git a/app/Services/Proxmox/Node/ProxmoxAllocationClient.php b/app/Services/Proxmox/Node/ProxmoxAllocationClient.php new file mode 100644 index 00000000000..89c57f299da --- /dev/null +++ b/app/Services/Proxmox/Node/ProxmoxAllocationClient.php @@ -0,0 +1,53 @@ +getHttpClient() + ->get('/api2/json/cluster/nextid') + ->json(); + + return (int) $this->getData($response); + } catch (Exception $e) { + throw new NextVMIDRetrievalException; + } + } + + /** + * @throws NextVMIDRetrievalException + */ + public function isVMIDAvailable(int $vmid): bool + { + try { + $this->getHttpClient() + ->bodyFormat('query') + ->get('/api2/json/cluster/nextid', [ + 'vmid' => $vmid, + ]); + + return true; + } catch (RequestException $e) { + if (str_contains($e->getMessage(), 'already exists')) { + return false; + } + + throw new NextVMIDRetrievalException(previous: $e); + } catch (Exception $e) { + throw new NextVMIDRetrievalException(previous: $e); + } + } +} diff --git a/app/Services/Proxmox/Node/ProxmoxCertificateClient.php b/app/Services/Proxmox/Node/ProxmoxCertificateClient.php new file mode 100644 index 00000000000..f418d2abc38 --- /dev/null +++ b/app/Services/Proxmox/Node/ProxmoxCertificateClient.php @@ -0,0 +1,43 @@ +getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/certificates/info') + ->json(); + + foreach ($this->getData($response) as $row) { + if (str_ends_with((string) Arr::get($row, 'filename', ''), 'pve-root-ca.pem')) { + return Arr::get($row, 'fingerprint'); + } + } + + return null; + } +} diff --git a/app/Services/Proxmox/Node/ProxmoxStatusClient.php b/app/Services/Proxmox/Node/ProxmoxStatusClient.php new file mode 100644 index 00000000000..be0c16051c0 --- /dev/null +++ b/app/Services/Proxmox/Node/ProxmoxStatusClient.php @@ -0,0 +1,24 @@ +getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/status') + ->json(); + + return NodeStatusData::fromRaw($this->getData($response)); + } +} diff --git a/app/Services/Proxmox/Node/ProxmoxStorageClient.php b/app/Services/Proxmox/Node/ProxmoxStorageClient.php new file mode 100644 index 00000000000..a4f2f212924 --- /dev/null +++ b/app/Services/Proxmox/Node/ProxmoxStorageClient.php @@ -0,0 +1,191 @@ + + * + * @throws RequestException + */ + public function getStorages(): DataCollection + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/storage') + ->json(); + + $response = $this->getData($response); + $storages = []; + foreach ($response as $storage) { + $storages[] = StorageData::fromRaw($storage); + } + + return StorageData::collect($storages, DataCollection::class); + } + + public function getStorage(string $name): StorageData + { + $response = $this->getHttpClientWithParams([ + 'storage' => $name, + ]) + ->get('/api2/json/nodes/{node}/storage/{storage}/status') + ->json(); + + $response = $this->getData($response); + $response['storage'] = $name; // Ensure the storage name is included in the response + + return StorageData::fromRaw($response); + } + + public function download( + StorageContentType $contentType, + string $storage, + string $fileName, + string $link, + ?bool $verifyCertificates = true, + ?ChecksumData $checksumData = null, + ) { + Assert::regex($link, '/^(http|https):\/\//', 'Invalid URL provided'); + + $payload = [ + 'content' => $contentType->toProxmoxString(), + 'filename' => $fileName, + 'url' => $link, + 'verify-certificates' => $verifyCertificates, + ]; + + if ($checksumData) { + $payload['checksum'] = $checksumData->checksum; + // PVE calls this `checksum-algorithm`. Sending `algorithm` is not + // ignored -- the API rejects unknown parameters -- so a download + // with a checksum failed outright rather than going unverified. + $payload['checksum-algorithm'] = $checksumData->algorithm->value; + } + + $response = $this->getHttpClientWithParams([ + 'storage' => $storage, + ]) + ->post('/api2/json/nodes/{node}/storage/{storage}/download-url', $payload) + ->json(); + + return $this->getData($response); + } + + /** + * File names PVE currently holds for one content type on a storage. + * + * Used to answer "is this image version already here?" without downloading + * it again. The content listing is the only honest source: a node may have + * been reinstalled, or the file pruned, since the panel last looked. + * + * @return array + * + * @throws RequestException + * @throws ConnectionException + */ + public function getFileNames(StorageContentType $contentType, string $storage): array + { + $response = $this->getHttpClientWithParams([ + 'storage' => $storage, + ]) + ->get('/api2/json/nodes/{node}/storage/{storage}/content', [ + 'content' => $contentType->toProxmoxString(), + ]) + ->json(); + + return collect($this->getData($response)) + ->pluck('volid') + ->filter() + // A volid is `storage:content/name`; only the name is comparable. + ->map(fn (string $volid) => Str::afterLast($volid, '/')) + ->values() + ->all(); + } + + public function deleteFile(StorageContentType $contentType, string $storage, string $fileName) + { + $response = $this->getHttpClientWithParams([ + 'storage' => $storage, + 'file' => "{$storage}:{$contentType->toProxmoxString()}/$fileName", + ]) + ->delete('/api2/json/nodes/{node}/storage/{storage}/content/{file}') + ->json(); + + return $this->getData($response); + } + + public function getISOs(string $storage): DataCollection + { + $response = $this->getHttpClientWithParams([ + 'storage' => $storage, + ]) + ->get('/api2/json/nodes/{node}/storage/{storage}/content?content=iso') + ->json(); + + $response = $this->getData($response); + + $isos = []; + + foreach ($response as $iso) { + $isos[] = new ISOData( + file_name: explode('/', $iso['volid'])[1], + size : $iso['size'], + createdAt: CarbonImmutable::createFromTimestamp($iso['ctime']), + ); + } + + return ISOData::collect($isos, DataCollection::class); + } + + /** + * @throws InvalidISOLinkException + * @throws ConnectionException + */ + public function getFileMetadata(string $link, bool $verifyCertificates = true): FileMetaData + { + Assert::regex($link, '/^(http|https):\/\//', 'Invalid URL provided'); + + try { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/query-url-metadata', [ + 'url' => $link, + 'verify-certificates' => $verifyCertificates, + ]) + ->json(); + } catch (RequestException $e) { + if (str_contains($e->getMessage(), "Can't connect to")) { + throw new InvalidISOLinkException; + } + + throw $e; + } + + if (Arr::get($response, 'success', 1) !== 1) { + throw new InvalidISOLinkException; + } + + $data = $this->getData($response); + + return FileMetaData::from([ + 'fileName' => $data['filename'], + 'mimeType' => $data['mimetype'], + 'size' => $data['size'], + ]); + } +} diff --git a/app/Services/Proxmox/ProxmoxClient.php b/app/Services/Proxmox/ProxmoxClient.php new file mode 100644 index 00000000000..3b9f284d233 --- /dev/null +++ b/app/Services/Proxmox/ProxmoxClient.php @@ -0,0 +1,112 @@ +server = $server; + $this->node = $server->node; + + return $this; + } + + public function setNode(Node $node): static + { + $this->node = $node; + + return $this; + } + + protected function getServer(): Server + { + Assert::isInstanceOf( + $this->server, + Server::class, + 'Server is not set or invalid.' + ); + + return $this->server; + } + + protected function getNode(): Node + { + if (! isset($this->node)) { + throw new \LogicException('Node is not set.'); + } + + return $this->node; + } + + public function getData(array|string $response): mixed + { + return $response['data'] ?? $response; + } + + /** + * Get a pre-configured HTTP client for Proxmox API requests. + * + * Note: Operations performed with the returned client are configured to throw + * a RequestException on HTTP request failures. + * + * @noinspection PhpDocRedundantThrowsInspection PhpStorm might flag this as redundant because the method itself doesn't throw. + * + * @throws RequestException + */ + public function getHttpClient( + bool $shouldAuthorize = true, + ): PendingRequest { + $client = Http::withOptions([ + 'verify' => $this->getNode()->verify_tls, + 'timeout' => config('convoy.guzzle.timeout'), + 'connect_timeout' => config('convoy.guzzle.connect_timeout'), + ]) + ->baseUrl("https://{$this->node->fqdn}:{$this->node->port}/") + ->withHeaders([ + 'Accept' => 'application/json', + 'Content-Type' => 'application/json', + ]); + + if ($shouldAuthorize) { + $client->withHeaders([ + 'Authorization' => "PVEAPIToken={$this->node->token_id}={$this->node->token_secret}", + ]); + } + + return $client->throw(function (Response $response) { + throw new RequestException($response); + }); + } + + /** + * @throws RequestException + */ + public function getHttpClientWithParams( + array $params = [], + bool $shouldAuthorize = true, + ): PendingRequest { + if (filled($this->node)) { + $params['node'] = $this->node->name; + } + + if (filled($this->server)) { + $params['server'] = $this->server->vmid; + } + + return $this->getHttpClient($shouldAuthorize) + ->withUrlParameters($params); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxActivityClient.php b/app/Services/Proxmox/Server/ProxmoxActivityClient.php new file mode 100644 index 00000000000..ad31ef39d10 --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxActivityClient.php @@ -0,0 +1,89 @@ + + * + * @throws RequestException + * @throws ConnectionException + */ + public function getTasks(int $startAt = 0, int $limitRows = 500): Collection + { + $response = $this->getHttpClientWithParams() + ->get( + '/api2/json/nodes/{node}/tasks', + [ + 'vmid' => $this->getServer()->vmid, + 'start' => $startAt, + 'limit' => $limitRows, + ] + ) + ->json(); + + return collect($this->getData($response))->map( + fn (array $task) => TaskData::fromRaw($task) + ); + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function getStatus(string $upid): TaskData + { + $response = $this->getHttpClientWithParams([ + 'task' => $upid, + ]) + ->get('/api2/json/nodes/{node}/tasks/{task}/status') + ->json(); + + return TaskData::fromRaw($this->getData($response)); + } + + /** + * @return Collection + * + * @throws RequestException + * @throws ConnectionException + */ + public function getLogsByTask(string $upid, int $startAt = 0, int $limitLinesTo = 100): Collection + { + $response = $this->getHttpClientWithParams([ + 'task' => $upid, + ]) + ->get('/api2/json/nodes/{node}/tasks/{task}/log', [ + 'start' => $startAt, + 'limit' => $limitLinesTo, + ]) + ->json(); + + return collect($this->getData($response))->map( + fn (array $log) => TaskLogData::fromRaw($log) + ); + } + + /** + * Stops a running task + * + * @throws RequestException + * @throws ConnectionException + */ + public function stop(string $upid): void + { + $this->getHttpClientWithParams([ + 'task' => $upid, + ]) + ->delete('/api2/json/nodes/{node}/tasks/{task}') + ->json(); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxBackupClient.php b/app/Services/Proxmox/Server/ProxmoxBackupClient.php new file mode 100644 index 00000000000..d87bbd592b8 --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxBackupClient.php @@ -0,0 +1,101 @@ + + * + * @throws RequestException + * @throws ConnectionException + */ + public function getBackups(Storage $storage): Collection + { + $response = $this->getHttpClientWithParams([ + 'storage' => $storage->name, + ]) + ->get('/api2/json/nodes/{node}/storage/{storage}/content', [ + 'content' => 'backup', + 'vmid' => $this->getServer()->vmid, + ]) + ->json(); + + return BackupData::collect( + array_map(fn (array $backup) => BackupData::fromRaw($backup), $this->getData($response)), + Collection::class + ); + } + + /** + * @return string UPID + * + * @throws RequestException + * @throws ConnectionException + */ + public function backup(BackupMode $mode, BackupCompressionType $compressionType, string $storage): string + { + $parsedMode = match ($mode) { + BackupMode::KILL => 'stop', + default => $mode->value, + }; + + $response = $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/vzdump', [ + 'vmid' => $this->getServer()->vmid, + 'storage' => $storage, + 'mode' => $parsedMode, + 'compress' => $compressionType === BackupCompressionType::NONE ? (int) false : $compressionType->value, + ]) + ->json(); + + return $this->getData($response); + } + + /** + * @return string UPID + * + * @throws RequestException + * @throws ConnectionException + */ + public function restore(Backup $backup): string + { + $response = $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu', [ + 'vmid' => $this->getServer()->vmid, + 'force' => true, + 'archive' => "{$backup->storage->name}:backup/{$backup->file_name}", + ]) + ->json(); + + return $this->getData($response); + } + + /** + * @return string UPID + * + * @throws RequestException + * @throws ConnectionException + */ + public function delete(Backup $backup): string + { + $response = $this->getHttpClientWithParams([ + 'storage' => $backup->storage->name, + 'backup' => "{$backup->storage->name}:backup/{$backup->file_name}", + ]) + ->delete('/api2/json/nodes/{node}/storage/{storage}/content/{backup}') + ->json(); + + return $this->getData($response); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxCloudinitClient.php b/app/Services/Proxmox/Server/ProxmoxCloudinitClient.php new file mode 100644 index 00000000000..c9d2a9b9139 --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxCloudinitClient.php @@ -0,0 +1,26 @@ +getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/config') + ->json(); + + return $this->getData($response); + } + + public function update(array $params = []) + { + $response = $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/config', $params) + ->json(); + + return $this->getData($response); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxConfigClient.php b/app/Services/Proxmox/Server/ProxmoxConfigClient.php new file mode 100644 index 00000000000..0d8eaf265fa --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxConfigClient.php @@ -0,0 +1,108 @@ +getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/config') + ->json(); + + return ServerConfigData::fromRaw($this->getData($response)); + } + + /** + * The raw PVE config map (unmodeled keys included, e.g. `unused0`). Used + * when removing a disk: `delete=scsiN` only *detaches* (the volume becomes + * `unusedN`), so we diff the raw `unused*` keys to find and destroy it. + * + * @return array + * + * @throws RequestException + * @throws ConnectionException + */ + public function getRawConfig(): array + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/config') + ->json(); + + return $this->getData($response); + } + + /** + * Current *and* pending config values, as `{key, value, pending}` rows. + * + * PVE cannot hot-add every device: a write against a running guest lands in + * the pending set and only becomes `value` at next boot. `/config` shows + * just the live side, so it is the wrong thing to ask "did that write take + * effect?" -- it reports the key as still absent. + * + * @return array> + * + * @throws RequestException + * @throws ConnectionException + */ + public function getPendingConfig(): array + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/pending') + ->json(); + + return $this->getData($response); + } + + /** + * Update the VM config. Pass the digest captured from getConfig() to make + * PVE reject the write if the config changed since it was read (optimistic + * concurrency); a mismatch surfaces as a RequestException. + * + * @throws RequestException + * @throws ConnectionException + */ + public function update(array $payload = [], ?string $digest = null) + { + if ($digest !== null) { + $payload['digest'] = $digest; + } + + try { + $response = $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/config', $payload) + ->json(); + } catch (RequestException $e) { + if ($digest !== null && $this->isConfigModifiedError($e)) { + throw new ConfigModifiedException; + } + + throw $e; + } + + return $this->getData($response); + } + + /** + * Whether the failure is Proxmox rejecting the write due to a digest + * mismatch ("detected modified configuration - file changed by other user"). + */ + private function isConfigModifiedError(RequestException $e): bool + { + return Str::contains( + Str::lower($e->getMessage()), + ['changed by other user', 'modified configuration'], + ); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxDiskClient.php b/app/Services/Proxmox/Server/ProxmoxDiskClient.php new file mode 100644 index 00000000000..1d501739606 --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxDiskClient.php @@ -0,0 +1,24 @@ +getHttpClientWithParams() + ->put('/api2/json/nodes/{node}/qemu/{server}/resize', [ + 'disk' => $disk->interface->value, + 'size' => "{$kibibytes}K", + ]) + ->json(); + + return $this->getData($response); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxFirewallClient.php b/app/Services/Proxmox/Server/ProxmoxFirewallClient.php new file mode 100644 index 00000000000..1af1107fa25 --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxFirewallClient.php @@ -0,0 +1,319 @@ +getHttpClientWithParams() + ->put('/api2/json/nodes/{node}/qemu/{server}/firewall/options', $payload) + ->json(); + + return $this->getData($response); + } + + /** + * The response envelope's `data`, as a list. + * + * {@see ProxmoxClient::getData()} falls back to the whole envelope when + * `data` is absent -- and because it uses `??`, a literal `{"data": null}` + * takes that branch too. Proxmox returns exactly that for an empty + * collection, which would otherwise feed the envelope itself into the + * per-item mappers below and fatal. + */ + private function getDataList(mixed $response): array + { + $data = is_array($response) ? ($response['data'] ?? null) : null; + + return is_array($data) ? $data : []; + } + + /** + * @throws RequestException + */ + public function getOptions(): FirewallOptionsData + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/options') + ->json(); + + return FirewallOptionsData::fromRaw($this->getDataList($response)); + } + + /** + * Rules in evaluation order. The index is the rule's identity in every + * other call here, and it renumbers on any insert, delete, or move -- so + * nothing may be cached against it. + * + * @return Collection + * + * @throws RequestException + */ + public function getRules(): Collection + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/rules') + ->json(); + + return FirewallRuleData::collect( + Arr::map($this->getDataList($response), fn (array $rule) => FirewallRuleData::fromRaw($rule)), + Collection::class, + ); + } + + /** + * @throws RequestException + */ + public function createRule(array $payload): void + { + $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/firewall/rules', $payload); + } + + /** + * @throws RequestException + */ + public function updateRule(int $position, array $payload): void + { + $this->getHttpClientWithParams(['pos' => $position]) + ->put('/api2/json/nodes/{node}/qemu/{server}/firewall/rules/{pos}', $payload); + } + + /** + * Deliberately separate from {@see updateRule()}: Proxmox ignores every + * other argument in a request carrying `moveto`, so folding the two + * together would silently discard the caller's edits. + * + * @throws RequestException + */ + public function moveRule(int $position, int $newPosition, ?string $digest = null): void + { + $payload = ['moveto' => $newPosition]; + + if ($digest !== null) { + $payload['digest'] = $digest; + } + + $this->getHttpClientWithParams(['pos' => $position]) + ->put('/api2/json/nodes/{node}/qemu/{server}/firewall/rules/{pos}', $payload); + } + + /** + * @throws RequestException + */ + public function deleteRule(int $position, ?string $digest = null): void + { + $client = $this->getHttpClientWithParams(['pos' => $position]); + + // The digest goes in the query string, not the body: Proxmox refuses a + // DELETE carrying content outright ("Unexpected content for method + // 'DELETE'"), regardless of what the content actually is. + if ($digest !== null) { + $client->withQueryParameters(['digest' => $digest]); + } + + $client->delete('/api2/json/nodes/{node}/qemu/{server}/firewall/rules/{pos}'); + } + + /** + * Aliases and IP sets nameable in a rule's source or destination, merged + * across this server's own config and the datacenter's. + * + * @return Collection + * + * @throws RequestException + */ + public function getRefs(): Collection + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/refs') + ->json(); + + return FirewallRefData::collect( + Arr::map($this->getDataList($response), fn (array $ref) => FirewallRefData::fromRaw($ref)), + Collection::class, + ); + } + + /** + * @return Collection + * + * @throws RequestException + */ + public function getLog(int $start = 0, int $limit = 100): Collection + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/log', [ + 'start' => $start, + 'limit' => $limit, + ]) + ->json(); + + return FirewallLogEntryData::collect( + Arr::map($this->getDataList($response), fn (array $line) => FirewallLogEntryData::fromRaw($line)), + Collection::class, + ); + } + + /** + * The cluster's predefined traffic macros. Cluster-scoped rather than + * node-scoped, but it answers on any node, and the base URL is already + * pointed at one. + * + * @return Collection + * + * @throws RequestException + */ + public function getMacros(): Collection + { + $response = $this->getHttpClient() + ->get('/api2/json/cluster/firewall/macros') + ->json(); + + return FirewallMacroData::collect( + Arr::map($this->getDataList($response), fn (array $macro) => FirewallMacroData::fromRaw($macro)), + Collection::class, + ); + } + + /** + * @return Collection + * + * @throws RequestException + */ + public function getIpsets(): Collection + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset') + ->json(); + + return IpsetData::collect(Arr::map($this->getData($response), function (array $item) { + /** @var array{name: string, digest: string, comment?: string|null} $item */ + + return [ + 'name' => $item['name'], + 'comment' => $item['comment'] ?? null, + ]; + }), Collection::class); + } + + /** + * @throws RequestException + */ + public function createIpset(string $name, string $comments = 'Generated by Convoy'): void + { + $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset', [ + 'name' => $name, + 'comment' => $comments, + ]); + } + + /** + * @throws RequestException + */ + public function deleteIpset(string|IpsetData $ipset): void + { + if ($ipset instanceof IpsetData) { + $ipset = $ipset->name; + } + + $this->getHttpClientWithParams([ + 'ipset' => $ipset, + ]) + ->delete('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}'); + } + + /** + * @return Collection + * + * @throws RequestException + */ + public function getLockedIps(string|IpsetData $ipset): Collection + { + if ($ipset instanceof IpsetData) { + $ipset = $ipset->name; + } + + $response = $this->getHttpClientWithParams([ + 'ipset' => $ipset, + ]) + ->get('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}') + ->json(); + + return LockedIpData::collect(Arr::map($this->getData($response), function (array $item) { + /** @var array{ cidr: string, comment: ?string, digest: string} $item */ + + return [ + 'ip' => Factory::parseRangeString($item['cidr']), + 'comment' => $item['comment'] ?? null, + 'originalIp' => $item['cidr'], + ]; + }), Collection::class); + } + + /** + * @throws RequestException + */ + public function lockIp(string|IpsetData $ipset, string|RangeInterface $ip, string $comments = 'Generated by Convoy'): void + { + if ($ipset instanceof IpsetData) { + $ipset = $ipset->name; + } + + if ($ip instanceof RangeInterface) { + $ip = $ip->toString(); + } + + $this->getHttpClientWithParams([ + 'ipset' => $ipset, + ]) + ->post('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}', [ + 'cidr' => $ip, + 'nomatch' => false, + 'comment' => $comments, + ]); + } + + /** + * @throws RequestException + */ + public function unlockIp(string|IpsetData $ipset, string|RangeInterface|LockedIpData $ip): void + { + if ($ipset instanceof IpsetData) { + $ipset = $ipset->name; + } + + if ($ip instanceof RangeInterface) { + $ip = $ip->toString(); + } + + if ($ip instanceof LockedIpData) { + $ip = $ip->originalIp; + } + + $this->getHttpClientWithParams([ + 'ipset' => $ipset, + 'address' => $ip, + ]) + ->delete('/api2/json/nodes/{node}/qemu/{server}/firewall/ipset/{ipset}/{address}'); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxGuestAgentClient.php b/app/Services/Proxmox/Server/ProxmoxGuestAgentClient.php new file mode 100644 index 00000000000..a7a2c8a9d58 --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxGuestAgentClient.php @@ -0,0 +1,314 @@ +withGuestAgentHandler(function () { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/info') + ->json(); + + return GuestAgentInfoData::fromRaw($this->getData($response)); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function getOsInfo(): GuestAgentOsInfoData + { + return $this->withGuestAgentHandler(function () { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/get-osinfo') + ->json(); + + return GuestAgentOsInfoData::fromRaw($this->getData($response)); + }); + } + + /** + * @return Collection + * + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function getNetworkInterfaces(): Collection + { + return $this->withGuestAgentHandler(function () { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/network-get-interfaces') + ->json(); + + // The result is usually in 'result' key + $data = $this->getData($response)['result'] ?? []; + + return GuestAgentNetworkInterfaceData::collect($data, Collection::class); + }); + } + + /** + * @return Collection + * + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function getFsInfo(): Collection + { + return $this->withGuestAgentHandler(function () { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/get-fsinfo') + ->json(); + + $data = $this->getData($response)['result'] ?? []; + + return GuestAgentFsInfoData::collect($data, Collection::class); + }); + } + + /** + * @return Collection + * + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function getUsers(): Collection + { + return $this->withGuestAgentHandler(function () { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/get-users') + ->json(); + + $data = $this->getData($response)['result'] ?? []; + + return GuestAgentUserData::collect($data, Collection::class); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function exec(array $command, ?string $input = null): int + { + return $this->withGuestAgentHandler(function () use ($command, $input) { + $payload = ['command' => $command]; + if ($input !== null) { + $payload['input-data'] = $input; + } + + $response = $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/agent/exec', $payload) + ->json(); + + return (int) ($this->getData($response)['result']['pid'] ?? 0); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function getExecStatus(int $pid): GuestAgentExecStatusData + { + return $this->withGuestAgentHandler(function () use ($pid) { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/exec-status', ['pid' => $pid]) + ->json(); + + return GuestAgentExecStatusData::fromRaw($this->getData($response)); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function fileRead(string $file): string + { + return $this->withGuestAgentHandler(function () use ($file) { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/file-read', ['file' => $file]) + ->json(); + + // Proxmox returns content (potentially truncated) + return $this->getData($response)['result']['content'] ?? ''; + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function fileWrite(string $file, string $content, bool $encode = true): void + { + $this->withGuestAgentHandler(function () use ($file, $content, $encode) { + $payload = [ + 'file' => $file, + 'content' => $content, + 'encode' => $encode ? 1 : 0, + ]; + + $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/agent/file-write', $payload) + ->json(); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function setUserPassword(string $username, string $password, bool $crypted = false): void + { + $this->withGuestAgentHandler(function () use ($username, $password, $crypted) { + $payload = [ + 'username' => $username, + 'password' => $password, + 'crypted' => $crypted ? 1 : 0, + ]; + + $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/agent/set-user-password', $payload) + ->json(); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function ping(): void + { + $this->withGuestAgentHandler(function () { + $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/agent/ping') + ->json(); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function shutdown(): void + { + $this->withGuestAgentHandler(function () { + $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/agent/shutdown') + ->json(); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function fstrim(): void + { + $this->withGuestAgentHandler(function () { + $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/agent/fstrim') + ->json(); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function getTime(): int + { + return $this->withGuestAgentHandler(function () { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/get-time') + ->json(); + + return (int) ($this->getData($response)['result'] ?? 0); + }); + } + + /** + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + public function getTimezone(): string + { + return $this->withGuestAgentHandler(function () { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/agent/get-timezone') + ->json(); + + // get-timezone returns { "zone": "UTC", "offset": 0 } + $data = $this->getData($response)['result'] ?? []; + + return $data['zone'] ?? ''; + }); + } + + /** + * @template T + * + * @param callable(): T $callback + * @return T + * + * @throws GuestAgentUnavailableException + * @throws RequestException + * @throws ConnectionException + */ + protected function withGuestAgentHandler(callable $callback) + { + try { + return $callback(); + } catch (RequestException $e) { + $response = $e->response->json(); + $message = $response['message'] ?? $e->getMessage(); + + if (is_string($message)) { + if (str_contains($message, 'QEMU guest agent is not running')) { + throw new GuestAgentUnavailableException('The QEMU Guest Agent is not running on this server. Please ensure it is installed and running.', $e); + } + + if (preg_match('/VM \d+ is not running/', $message)) { + throw new GuestAgentUnavailableException('The server is not running. Please start the server to perform this action.', $e); + } + } + + throw $e; + } + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxPowerClient.php b/app/Services/Proxmox/Server/ProxmoxPowerClient.php new file mode 100644 index 00000000000..583c66f1cff --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxPowerClient.php @@ -0,0 +1,44 @@ + 'reboot', + PowerCommand::RESET => 'reset', + PowerCommand::RESUME => 'resume', + PowerCommand::SHUTDOWN => 'shutdown', + PowerCommand::START => 'start', + PowerCommand::KILL => 'stop', + PowerCommand::SUSPEND => 'suspend', + }; + + $response = $this->getHttpClientWithParams([ + 'action' => $parsedAction, + ]) + ->post('/api2/json/nodes/{node}/qemu/{server}/status/{action}', [ + ...($parsedAction !== 'suspend' ? ['timeout' => 30] : ['skiplock' => false]), + ]) + ->json(); + + $upid = $this->getData($response); + + return is_string($upid) ? $upid : null; + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxServerClient.php b/app/Services/Proxmox/Server/ProxmoxServerClient.php new file mode 100644 index 00000000000..78909139e6a --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxServerClient.php @@ -0,0 +1,148 @@ +getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/status/current') + ->json(); + + $state = ServerStateData::fromRaw($this->getData($response)); + + // Write-through: this is the only place in the app that reads one + // guest's status live, so recording it here means no caller can forget + // to. It is what keeps a server list -- which reads the cache and never + // PVE -- from showing a stale badge in the minute after a power action, + // and it costs one cache write on a request that just paid for a round + // trip to Proxmox. + $this->guestStates->observe($this->getServer(), $state->powerState); + + return $state; + } + + /** + * @return string Job UPID + * + * @throws RequestException + * @throws ConnectionException + */ + /** + * Build the guest from an image version rather than cloning a template. + * + * A clone inherited every hardware setting from the template's own config, + * which is why the panel never had to store any. There is nothing to + * inherit here: the VM is assembled entirely from arguments, so this call + * carries the whole profile and is the one place the definition's hardware + * becomes a real machine. + * + * @param array $volids Import sources on the node, keyed by disk role. + * @return string Job UPID + * + * @throws RequestException + * @throws ConnectionException + */ + public function create(ImageVersion $version, array $volids): string + { + $server = $this->getServer(); + $definition = $version->definition; + $hardware = $definition->effectiveHardware(); + $storage = $server->storage->name; + + $bootSlot = $hardware['boot_disk_slot'] ?? 'scsi0'; + $system = $volids[ImageDiskRole::SYSTEM->value] + ?? throw new ConflictHttpException('This image version has no system disk to import.'); + + $payload = array_merge(OsProfiles::proxmoxKeys($hardware), [ + 'vmid' => $server->vmid, + 'name' => $server->hostname, + // Its own column, and passed explicitly: Proxmox derives the + // cloud-init drive type from it, so it must not be left to whatever + // happens to be in the profile blob. + 'ostype' => $definition->ostype, + 'cores' => $server->cpu, + 'memory' => (int) ($server->memory / 1024 / 1024), + + // Size 0 means "take the source's size". The imported disk arrives + // at the image's own virtual size and is grown to the plan + // afterwards, because Proxmox can grow a disk and cannot shrink one. + $bootSlot => "{$storage}:0,import-from={$system}", + + // Without this the guest can come up on an empty NIC or the + // cloud-init drive; a clone used to inherit a boot order. + 'boot' => $hardware['boot'] ?? "order={$bootSlot}", + ]); + + // Only OVMF images carry a varstore, and it is shipped verbatim rather + // than regenerated: it holds the boot entry and the enrolled Secure + // Boot keys, so a fresh one would leave Windows unbootable. + if (isset($volids[ImageDiskRole::EFIVARS->value])) { + $payload['efidisk0'] = sprintf( + '%s:0,import-from=%s,efitype=4m', + $storage, + $volids[ImageDiskRole::EFIVARS->value], + ); + } + + if (filled($cloudinitSlot = $hardware['cloudinit_slot'] ?? 'ide2')) { + $payload[$cloudinitSlot] = "{$storage}:cloudinit"; + } + + $response = $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu', $payload) + ->json(); + + return $this->getData($response); + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function delete() + { + $response = $this->getHttpClientWithParams() +// ->withOptions([ +// 'query' => [ +// 'destroy-unreferenced-disks' => true, +// 'purge' => true, +// ], +// ]) + ->delete('/api2/json/nodes/{node}/qemu/{server}') + ->json(); + + return $this->getData($response); + } + + public function addUser(RealmType $realmType, string $userId, string $roleId) + { + $response = $this->getHttpClient() + ->put('/api2/json/access/acl', [ + 'path' => '/vms/'.$this->server->vmid, + 'users' => $userId.'@'.$realmType->value, + 'roles' => $roleId, + ]) + ->json(); + + return $this->getData($response); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxSnapshotClient.php b/app/Services/Proxmox/Server/ProxmoxSnapshotClient.php new file mode 100644 index 00000000000..4c5e181a9bc --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxSnapshotClient.php @@ -0,0 +1,77 @@ + + * + * @throws RequestException + * @throws ConnectionException + */ + public function getSnapshots(): Collection + { + $response = $this->getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/snapshot') + ->json(); + + return SnapshotData::collect($this->getData($response), Collection::class); + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function create(string $name, ?string $description = null, bool $includesRam = false): string + { + $payload = array_filter([ + 'snapname' => $name, + 'description' => $description, + 'vmstate' => $includesRam ? 1 : null, + ], fn ($value) => filled($value)); + + $response = $this->getHttpClientWithParams() + ->post('/api2/json/nodes/{node}/qemu/{server}/snapshot', $payload) + ->json(); + + return $this->getData($response); + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function restore(string $name): string + { + $response = $this->getHttpClientWithParams([ + 'snapshot' => $name, + ]) + ->asForm() + ->post('/api2/json/nodes/{node}/qemu/{server}/snapshot/{snapshot}/rollback') + ->json(); + + return $this->getData($response); + } + + /** + * @throws RequestException + * @throws ConnectionException + */ + public function delete(string $name): string + { + $response = $this->getHttpClientWithParams([ + 'snapshot' => $name, + ]) + ->delete('/api2/json/nodes/{node}/qemu/{server}/snapshot/{snapshot}') + ->json(); + + return $this->getData($response); + } +} diff --git a/app/Services/Proxmox/Server/ProxmoxStatisticsClient.php b/app/Services/Proxmox/Server/ProxmoxStatisticsClient.php new file mode 100644 index 00000000000..6cc110d59fa --- /dev/null +++ b/app/Services/Proxmox/Server/ProxmoxStatisticsClient.php @@ -0,0 +1,45 @@ +getHttpClientWithParams() + ->get('/api2/json/nodes/{node}/qemu/{server}/rrddata', [ + 'timeframe' => $from->value, + 'cf' => $consolidator->value, + ]) + ->json(); + + $test = Arr::map($this->getData($response), function (array $statistic) { + return new ServerTimepointData( + cpuUsed : $statistic['cpu'] ?? 0, + memoryUsed: $statistic['mem'] ?? 0, + network : new ServerNetworkData( + in : $statistic['netin'] ?? 0, + out: $statistic['netout'] ?? 0, + ), + disk : new ServerDiskData( + write: $statistic['diskwrite'] ?? 0, + read : $statistic['diskread'] ?? 0, + ), + timestamp : CarbonImmutable::createFromTimestamp($statistic['time']), + ); + }); + + return ServerTimepointData::collect($test); + } +} diff --git a/app/Services/Servers/AllocationService.php b/app/Services/Servers/AllocationService.php index 04adaed2b76..2300020877b 100644 --- a/app/Services/Servers/AllocationService.php +++ b/app/Services/Servers/AllocationService.php @@ -1,187 +1,446 @@ configClient->setServer($server)->getConfig(); } - public function syncSettings(Server $server) + /** + * @throws RequestException + * @throws ConnectionException + */ + public function getDisks(Server $server): Collection { - return $this->updateHardware($server, $server->cpu, $server->memory); + return $this->configClient->setServer($server)->getConfig()->disks; } /** - * @return Collection + * @throws RequestException + * @throws ConnectionException */ - public function getDisks(Server $server): Collection + public function getBootOrder(Server $server): Collection { - $isos = $server->node->isos; + return $this->configClient->setServer($server)->getConfig()->bootOrder; + } - $disks = array_values(array_filter($this->repository->setServer($server)->getConfig(), function ($disk) { - return in_array($disk['key'], array_column(DiskInterface::cases(), 'value')); - })); + /** + * @throws RequestException + * @throws ConnectionException + */ + public function syncSettings(Server $server): void + { + $config = $this->configClient->setServer($server)->getConfig(); - return collect(Arr::map($disks, function ($rawDisk) use ($isos, $server) { - $disk = [ - 'interface' => DiskInterface::from(Arr::get($rawDisk, 'key')), - 'is_primary_disk' => false, - 'is_media' => false, - 'media_name' => null, - 'size' => 0, - ]; + // Only push cores/memory that actually differ, so an unchanged sync doesn't + // enqueue a redundant Proxmox "Configure" task. $config->memory is in bytes; + // PVE's payload wants integer MiB. + $desiredMemoryMib = (int) ($server->memory / 1024 / 1024); + $currentMemoryMib = (int) ($config->memory / 1024 / 1024); - $value = Arr::get($rawDisk, 'pending') ?? Arr::get($rawDisk, 'value'); + $payload = []; + if ($config->cpu->coreCount !== $server->cpu) { + $payload['cores'] = $server->cpu; + } + if ($currentMemoryMib !== $desiredMemoryMib) { + $payload['memory'] = $desiredMemoryMib; + } - preg_match("/size=(\d+\w?)/s", $value, $sizeMatches); + // Templates are not required to carry a serial device, and without one + // the terminal console has nothing to attach to. Added here rather than + // in a job of its own so it rides the sync that already runs at deploy, + // and so a rebuild repairs a server that predates this. + $payload = $this->serialConsole->withDevice( + $payload, + $config->serialDevices->isNotEmpty(), + ); + + if ($payload !== []) { + $this->configClient->setServer($server)->update($payload); + } - if (array_key_exists(1, $sizeMatches)) { - $disk['size'] = $this->convertToBytes($sizeMatches[1]); + // We're assuming the largest disk is the disk to be resized. + /** @var ?DiskData $disk */ + $disk = $config->disks->reduce(function (?DiskData $carry, DiskData $disk) { + if ($carry === null || $disk->size > $carry->size) { + return $disk; } - if (str_contains($value, 'media')) { - $disk['is_media'] = true; - // this piece of code adds the name of the mounted ISO - if (preg_match("/\/(.*\.iso)/s", $value, $fileNameMatches)) { - if ($iso = $isos->where('file_name', $fileNameMatches[1])->first()) { - $disk['media_name'] = $iso->name; - } - } elseif (str_contains($value, 'cloudinit')) { - $disk['media_name'] = 'Cloudinit'; - } - } else { - // if its not the ISO, we'll check if its the boot disk by comparing the size to the disk size on the eloquent record of the server - $upperBound = $server->disk + 1024; - $lowerBound = $server->disk - 1024; - - if ($disk['size'] < $upperBound && $disk['size'] > $lowerBound) { - $disk['is_primary_disk'] = true; - } - } + return $carry; + }); - return DiskData::from($disk); - })); + if ($disk !== null && $server->disk > $disk->size) { + $this->diskClient->setServer($server)->setDiskSize( + $disk, + $server->disk, + ); + } } /** - * @return Collection + * Allocate any secondary (non-primary) data disks that aren't on the VM yet. + * + * Each `server_disks` row that isn't the primary is materialized as a fresh + * Proxmox volume via the `STORAGE:SIZE_GiB` allocation syntax on the next + * free scsi slot. Idempotent + retry-safe: + * - the chosen interface is persisted to the row *before* the config write, + * so a `ConfigureVmJob` retry reuses the same slot instead of allocating a + * second volume; + * - a disk already present on the VM (its interface appears in the live + * config) is skipped; + * - all pending disks go out in ONE digest-guarded config write (avoids a + * stale-digest failure between disks and stays atomic). No pending disks ⇒ + * no empty write. + * + * @throws RequestException + * @throws ConnectionException + * @throws NoAvailableDiskInterfaceException */ - public function getBootOrder(Server $server): Collection + public function syncDisks(Server $server): void { - $disks = $this->getDisks($server); + $secondaryDisks = $server->disks() + ->where('is_primary', false) + ->orderBy('disk_index') + ->get(); + + if ($secondaryDisks->isEmpty()) { + return; + } + + $config = $this->configClient->setServer($server)->getConfig(); + + // scsi slot numbers already taken on the VM (the primary may be scsi0, or + // on another bus entirely — we only ever place secondaries on scsi). + $usedScsiSlots = $config->disks + ->filter(fn (DiskData $disk) => $disk->interface->getBaseType() === 'scsi') + ->map(fn (DiskData $disk) => $disk->interface->getSlot()) + ->values() + ->all(); + + // Assign (and persist) an interface to any disk that doesn't have one yet. + foreach ($secondaryDisks as $disk) { + if ($disk->interface !== null) { + continue; + } - $raw = collect($this->repository->setServer($server)->getConfig())->where('key', 'boot')->firstOrFail(); + $slot = DiskInterface::getNextAvailableSlot('scsi', $usedScsiSlots); + if ($slot === null) { + throw new NoAvailableDiskInterfaceException; + } - $untaggedDisks = array_values(array_filter(explode(';', Arr::last(explode('=', $raw['pending'] ?? $raw['value']))), function ($disk) { - return ! ctype_space($disk) && in_array($disk, array_column(DiskInterface::cases(), 'value')); // filter literally whitespace entries because Proxmox keeps empty strings for some reason >:( - })); + $disk->interface = "scsi{$slot}"; + $disk->save(); + $usedScsiSlots[] = $slot; + } - $taggedDisks = []; + // Build one write of the disks not already present on the VM. + $existingInterfaces = $config->disks + ->map(fn (DiskData $disk) => $disk->interface->value) + ->all(); - foreach ($untaggedDisks as $untaggedDisk) { - if ($disk = $disks->where('interface', '=', DiskInterface::from($untaggedDisk))->first()) { - array_push($taggedDisks, $disk); + $payload = []; + foreach ($secondaryDisks as $disk) { + if (in_array($disk->interface, $existingInterfaces, true)) { + continue; } + + // Allocation syntax takes whole GiB; sizes are kept GiB-aligned. + $sizeGib = max(1, (int) ceil($disk->size / (1024 ** 3))); + $payload[$disk->interface] = "{$disk->storage->name}:{$sizeGib}"; } - return collect($taggedDisks); + if ($payload !== []) { + $this->configClient->setServer($server)->update($payload, $config->digest); + } } - public function setBootOrder(Server $server, array $disks) + /** + * Add a secondary data disk to a server: persist the row, then allocate it + * on Proxmox (reuses {@see syncDisks}, so slot assignment + idempotency are + * shared). Capacity is validated by the request layer. + * + * @throws RequestException + * @throws ConnectionException + * @throws NoAvailableDiskInterfaceException + */ + public function addDisk(Server $server, int $storageId, int $sizeBytes): ServerDisk { - return $this->repository->setServer($server)->update([ - 'boot' => count($disks) > 0 ? 'order='.Arr::join($disks, ';') : '', + $disk = $server->disks()->create([ + 'storage_id' => $storageId, + 'size' => $sizeBytes, + 'interface' => null, + 'is_primary' => false, + 'disk_index' => (int) $server->disks()->max('disk_index') + 1, ]); + + $this->syncDisks($server); + + return $disk->refresh(); } - public function updateHardware(Server $server, int $cpu, int $memory) + /** + * Grow a secondary disk. Proxmox resize only ever grows, so a shrink is + * rejected up front. If the disk isn't on the VM yet (still pending build), + * only the row is updated — the build allocates it at the new size. + * + * @throws RequestException + * @throws ConnectionException + * @throws CannotModifyPrimaryDiskException + * @throws CannotShrinkDiskException + */ + public function resizeDisk(Server $server, ServerDisk $disk, int $newSizeBytes): void { - $memMiB = (int) ($memory / 1048576); + if ($disk->is_primary) { + throw new CannotModifyPrimaryDiskException; + } - $raw = collect($this->repository->setServer($server)->getConfig()); - $currentCores = $raw->where('key', '=', 'cores')->first()['value'] ?? null; - $currentMem = $raw->where('key', '=', 'memory')->first()['value'] ?? null; + if ($newSizeBytes < $disk->size) { + throw new CannotShrinkDiskException; + } - $payload = []; - if ((string) $currentCores !== (string) $cpu) { - $payload['cores'] = $cpu; + if ($newSizeBytes === $disk->size) { + return; } - if ((string) $currentMem !== (string) $memMiB) { - $payload['memory'] = $memMiB; + + if ($disk->interface !== null) { + $config = $this->configClient->setServer($server)->getConfig(); + $onVm = $config->disks->first( + fn (DiskData $d) => $d->interface->value === $disk->interface, + ); + + if ($onVm !== null) { + $this->diskClient->setServer($server)->setDiskSize($onVm, $newSizeBytes); + } + } + + $disk->size = $newSizeBytes; + $disk->save(); + } + + /** + * How many times to re-read the config looking for the detached volume to + * surface as `unusedN`, and how long to wait between reads (µs). + * + * On a *running* VM `delete=scsiN` only schedules the hot-unplug: the API + * call returns before QEMU confirms it, and the volume moves to `unusedN` + * a moment later — so an immediate single re-read races it and misses the + * freed volume (leaving it orphaned on disk). We poll instead. On a stopped + * VM the entry is there on the first read, so the loop exits immediately. + */ + private const UNUSED_POLL_ATTEMPTS = 12; + + private const UNUSED_POLL_DELAY_US = 500_000; + + /** + * Remove a secondary disk and reclaim its space. `delete=scsiN` only + * *detaches* on Proxmox (the volume lingers as `unusedN`); we then destroy + * that freed volume so nothing is left orphaned on the storage. + * + * @throws RequestException + * @throws ConnectionException + * @throws CannotModifyPrimaryDiskException + */ + public function removeDisk(Server $server, ServerDisk $disk): void + { + if ($disk->is_primary) { + throw new CannotModifyPrimaryDiskException; } - if (empty($payload)) { + // Never built (no interface assigned) — nothing on the VM to detach. + if ($disk->interface === null) { + $disk->delete(); + return; } - return $this->repository->setServer($server)->update($payload); + $client = $this->configClient->setServer($server); + + $config = $client->getConfig(); + $onVm = $config->disks->first( + fn (DiskData $d) => $d->interface->value === $disk->interface, + ); + + if ($onVm !== null) { + // Detach: the volume becomes an `unusedN` entry (async on a running + // VM — see the poll constants). Match on the exact volume id, not a + // before/after count, so a concurrent unused slot can't fool us. + $client->update(['delete' => $disk->interface], $config->digest); + $this->purgeDetachedVolume($client, $onVm->volume); + } + + $disk->delete(); + } + + /** + * Poll the raw config until the just-detached volume surfaces as an + * `unusedN` key, then delete that key to destroy the underlying volume. + * Best-effort: if it never appears within the window we stop (the disk is + * already detached; a leftover volume is preferable to blocking forever). + * + * @throws RequestException + * @throws ConnectionException + */ + private function purgeDetachedVolume(ProxmoxConfigClient $client, string $volume): void + { + for ($attempt = 0; $attempt < self::UNUSED_POLL_ATTEMPTS; $attempt++) { + $raw = $client->getRawConfig(); + $key = $this->findUnusedKeyForVolume($raw, $volume); + + if ($key !== null) { + $client->update(['delete' => $key], $raw['digest'] ?? null); + + return; + } + + usleep(self::UNUSED_POLL_DELAY_US); + } } - public function mountIso(Server $server, ISO $iso) + /** + * The `unusedN` config key whose value references $volume, if any. PVE + * renders the unused entry as the bare volume id (no `,size=` suffix), so + * compare on the volume id portion only. + * + * @param array $raw + */ + private function findUnusedKeyForVolume(array $raw, string $volume): ?string { - // we'll be using IDE by default for now - $ideIndex = 0; // max IDE index is '3' - $disks = $this->getDisks($server); - if ($disks->where('media_name', '=', $iso->name)->first()) { - throw new IsoAlreadyMountedException(); + foreach ($raw as $key => $value) { + if (preg_match('/^unused\d+$/', $key) !== 1) { + continue; + } + + if (is_string($value) && explode(',', $value)[0] === $volume) { + return $key; + } } - $arrayToCheckForAvailableIdeIndex = Arr::pluck($this->repository->setServer($server)->getConfig(), 'key'); + return null; + } + + public function setBootOrder(Server $server, array $disks) + { + return $this->configClient->setServer($server)->update([ + 'boot' => count($disks) > 0 ? 'order='.Arr::join($disks, ';') : '', + ]); + } + + public function mountISO(Server $server, ISO $iso): void + { + // Put the file on the node first. The library is panel-wide, so this + // node may never have seen this ISO -- and mounting a volume that is + // not there gives the guest an empty drive rather than an error. + $this->isoResidency->ensureResident($server->node, $iso); + + // One read tells us everything: whether the ISO is already mounted, + // which IDE slot is free, and the digest to guard the write with (a + // concurrent mount could otherwise claim the same slot). + $config = $this->configClient->setServer($server)->getConfig(); + + if ($this->findMountedISODisk($config->disks, $iso, $server->node)) { + throw new ISOAlreadyMountedException; + } + + $ideIndex = 0; // max IDE index is '3' + $usedKeys = $config->disks + ->map(fn (DiskData $disk) => $disk->interface->value) + ->all(); for ($i = 0; $i <= 4; $i++) { if ($i === 4) { - throw new NoAvailableDiskInterfaceException(); + throw new NoAvailableDiskInterfaceException; } - if (! in_array("ide$i", $arrayToCheckForAvailableIdeIndex)) { + if (! in_array("ide$i", $usedKeys)) { $ideIndex = $i; break; } } - $this->repository->update([ - "ide$ideIndex" => "{$server->node->iso_storage}:iso/{$iso->file_name},media=cdrom", - ]); + $this->configClient->update([ + "ide$ideIndex" => $this->isoVolume($iso, $server->node).',media=cdrom', + ], $config->digest); } - public function unmountIso(Server $server, ISO $iso) + public function unmountISO(Server $server, ISO $iso): void { - $disks = $this->getDisks($server); - if ($disk = $disks->where('media_name', '=', $iso->name)->first()) { - $this->repository->update(['delete' => $disk->interface->value]); - } else { - throw new IsoAlreadyUnmountedException(); + // Read the full config (not just the disks) so we can guard the delete + // with its digest — the interface we delete is derived from this read. + $config = $this->configClient->setServer($server)->getConfig(); + + $disk = $this->findMountedISODisk($config->disks, $iso, $server->node); + + if ($disk === null) { + throw new ISOAlreadyUnmountedException; } + + $this->configClient->update(['delete' => $disk->interface->value], $config->digest); } - public function convertToBytes(string $from): ?int + /** + * The Proxmox volume string a mounted copy of this ISO takes, e.g. + * "local:iso/debian-12.iso" — the same value {@see mountISO} writes. + * + * It depends on the node, because the storage the file lands on does: the + * library entry itself has no storage any more. + */ + private function isoVolume(ISO $iso, Node $node): string { - $units = ['B', 'K', 'M', 'G', 'T', 'P']; - $number = (int) substr($from, 0, -1); - $suffix = strtoupper(substr($from, -1)); - - //B or no suffix - if (is_numeric(substr($suffix, 0, 1))) { - return preg_replace('/[^\d]/', '', $from); - } + return $this->isoResidency->volume($node, $iso); + } - $exponent = array_flip($units)[$suffix] ?? null; - if ($exponent === null) { - return null; - } + /** + * Find the cdrom disk this ISO is mounted on, if any. Matches on the + * backing volume (not a non-existent "media_name"), so it correctly + * identifies the mount instead of never matching. + * + * @param Collection $disks + */ + public function findMountedISODisk(Collection $disks, ISO $iso, Node $node): ?DiskData + { + $volume = $this->isoVolume($iso, $node); - return $number * (1024 ** $exponent); + return $disks->first(fn (DiskData $disk) => $disk->diskMediaType === DiskMediaType::CDROM + && $disk->volume === $volume); } } diff --git a/app/Services/Servers/CloudinitService.php b/app/Services/Servers/CloudinitService.php index c90eafa91a4..cc5bccccf78 100644 --- a/app/Services/Servers/CloudinitService.php +++ b/app/Services/Servers/CloudinitService.php @@ -1,149 +1,120 @@ configRepository->setServer($server)->getConfig())->where('key', '=', 'sshkeys')->first()['value'] ?? ''; - - return rawurldecode($raw); - } + public function __construct(private ProxmoxConfigClient $configClient) {} /** - * @param string $password - * @param array $params - * @return mixed - */ - - /** - * @param array $params - * @return mixed + * Sets the hostname and search domain for a server in Proxmox. + * + * @throws RequestException */ - public function updateHostname(Server $server, string $hostname) + public function setHostname(Server $server, string $hostname): void { - $raw = collect($this->configRepository->setServer($server)->getConfig()); - $currentName = $raw->where('key', '=', 'name')->first()['value'] ?? null; - $currentSearch = $raw->where('key', '=', 'searchdomain')->first()['value'] ?? null; + $config = $this->configClient->setServer($server)->getConfig(); + // Write only what differs, so an unchanged hostname doesn't enqueue a + // redundant Proxmox "Configure" task. $payload = []; - if ($currentName !== $hostname) { + if ($config->name !== $hostname) { $payload['name'] = $hostname; } - if ($currentSearch !== $hostname) { + if ($config->cloudinit->searchDomain !== $hostname) { $payload['searchdomain'] = $hostname; } - if (empty($payload)) { + if ($payload === []) { return; } - $this->configRepository->setServer($server)->update($payload); + $this->configClient->setServer($server)->update($payload); } - public function getNameservers(Server $server) + /** + * @return string[] + * + * @throws RequestException + */ + public function getNameservers(Server $server): array { - $nameservers = collect($this->configRepository->setServer($server)->getConfig())->where('key', '=', 'nameserver')->first(); + $nameservers = collect($this->configClient->setServer($server)->getConfig())->where('key', '=', 'nameserver')->first(); return $nameservers ? explode(' ', $nameservers['value']) : []; } - public function updateNameservers(Server $server, array $nameservers) + public function setNameservers(Server $server, array $nameservers): void { $payload = [ ...(count($nameservers) > 0 ? ['nameserver' => implode(' ', $nameservers)] : []), ...(count($nameservers) === 0 ? ['delete' => 'nameserver'] : []), ]; - return $this->configRepository->setServer($server)->update($payload); - } - - public function getIpConfig(Server $server): AddressConfigData - { - $rawConfig = collect($this->configRepository->setServer($server)->getConfig())->where('key', '=', 'ipconfig0')->first()['value']; - - $config = [ - 'ipv4' => null, - 'ipv6' => null, - ]; - - if ($rawConfig) { - $configs = explode(',', $rawConfig); - - Arr::map($configs, function ($value) use (&$config) { - $property = explode('=', $value); - - if ($property[0] === 'ip') { - $cidr = explode('/', $property[1]); - $config['ipv4']['address'] = $cidr[0]; - $config['ipv4']['cidr'] = $cidr[1]; - } - if ($property[0] === 'ip6') { - $cidr = explode('/', $property[1]); - $config['ipv6']['address'] = $cidr[0]; - $config['ipv6']['cidr'] = $cidr[1]; - } - if ($property[0] === 'gw') { - $config['ipv4']['gateway'] = $property[1]; - } - if ($property[0] === 'gw6') { - $config['ipv6']['gateway'] = $property[1]; - } - }); - } - - return AddressConfigData::from($config); + $this->configClient->setServer($server)->update($payload); } /** - * @param string|array $config - * @return mixed|void + * Updates the IP configuration for a server in Proxmox. + * Configures IPv4 and IPv6 addresses with their respective gateways. * - * @throws ProxmoxConnectionException + * @throws RequestException */ - public function updateIpConfig(Server $server, CloudinitAddressConfigData $addresses) + public function setIpConfig(Server $server, ?Address $ipv4, ?Address $ipv6): void { $payload = []; - if ($addresses?->ipv4) { - $ipv4 = $addresses->ipv4; - $payload[] = "ip={$ipv4->address}/{$ipv4->cidr}"; + if ($ipv4) { + $payload[] = "ip={$ipv4->ip}/{$ipv4->prefix_length}"; $payload[] = 'gw='.$ipv4->gateway; } - if ($addresses?->ipv6) { - $ipv6 = $addresses->ipv6; - $payload[] = "ip6={$ipv6->address}/{$ipv6->cidr}"; + if ($ipv6) { + $payload[] = "ip6={$ipv6->ip}/{$ipv6->prefix_length}"; $payload[] = 'gw6='.$ipv6->gateway; } - $desired = Arr::join($payload, ','); - $current = collect($this->configRepository->setServer($server)->getConfig()) - ->where('key', '=', 'ipconfig0')->first()['value'] ?? ''; + $payload = Arr::join($payload, ','); - if ($current === $desired) { - return; - } + // The set of ipconfig keys is derived from the NICs we just read, so + // guard the write with that read's digest (optimistic concurrency). + $config = $this->configClient->setServer($server)->getConfig(); + + // Parse our own desired string through the same codec as the stored config, + // so the comparison is order/format-insensitive, and skip NICs that are + // already at the target ipconfig (avoids a redundant Configure task). + $desired = IpConfigData::fromString($payload); - if ($desired === '') { - return $this->configRepository->setServer($server)->update(['delete' => 'ipconfig0']); + /** @var array $networkDevices */ + $networkDevices = $config->networkDevices + ->filter(function (NetworkDeviceData $device) use ($config, $desired) { + $current = $config->cloudinit->ipConfigs->get($device->id); + + return $current === null || $current->toArray() !== $desired->toArray(); + }) + ->mapWithKeys(fn (NetworkDeviceData $device) => ["ipconfig$device->id" => $payload]) + ->all(); + + if ($networkDevices === []) { + return; } - return $this->configRepository->setServer($server)->update(['ipconfig0' => $desired]); + $this->configClient->update($networkDevices, $config->digest); } } diff --git a/app/Services/Servers/DisplayConsoleService.php b/app/Services/Servers/DisplayConsoleService.php new file mode 100644 index 00000000000..31b2e04fa43 --- /dev/null +++ b/app/Services/Servers/DisplayConsoleService.php @@ -0,0 +1,104 @@ +configClient->setServer($server)->getPendingConfig(); + + foreach ($rows as $row) { + if (($row['key'] ?? null) !== self::DEVICE) { + continue; + } + + // `value` is what the running guest has; `pending` is what it will + // have at next boot. A row with only the latter is the mid-state + // between changing the display and restarting. + $live = (string) ($row['value'] ?? ''); + $queued = (string) ($row['pending'] ?? ''); + $enabled = $this->hasDisplay($live); + + return new DisplayConsoleData( + enabled: $enabled, + restartRequired: ! $enabled && $queued !== '' && $this->hasDisplay($queued), + display: $live === '' ? null : $live, + ); + } + + // No `vga` key at all means PVE's default, which has a display. + return new DisplayConsoleData(enabled: true, restartRequired: false, display: null); + } + + /** + * Give the VM a graphical display, unless it already has one. + * + * @throws RequestException + * @throws ConnectionException + */ + public function enable(Server $server): DisplayConsoleData + { + $status = $this->status($server); + + if ($status->enabled || $status->restartRequired) { + return $status; + } + + $this->configClient->setServer($server)->update([ + self::DEVICE => self::DISPLAY, + ]); + + return $this->status($server); + } + + /** + * Whether a `vga` value leaves QEMU with a VNC server. + * + * The value carries options (`std,memory=32`), and an empty one is the + * default rather than an absence, so only the type is judged. + */ + private function hasDisplay(string $value): bool + { + $type = Str::before($value, ','); + + return $type !== 'none' && ! Str::startsWith($type, 'serial'); + } +} diff --git a/app/Services/Servers/NetworkService.php b/app/Services/Servers/NetworkService.php deleted file mode 100644 index 7ee57ca9af3..00000000000 --- a/app/Services/Servers/NetworkService.php +++ /dev/null @@ -1,267 +0,0 @@ -firewallRepository->setServer($server); - - $addresses = array_column($this->firewallRepository->getLockedIps($name), 'cidr'); - - foreach ($addresses as $address) { - $this->firewallRepository->unlockIp($name, $address); - } - - return $this->firewallRepository->deleteIpset($name); - } - - public function clearIpsets(Server $server): void - { - $this->firewallRepository->setServer($server); - - $ipSets = array_column($this->firewallRepository->getIpsets(), 'name'); - - foreach ($ipSets as $ipSet) { - $this->deleteIpset($server, $ipSet); - } - } - - public function lockIps(Server $server, array $addresses, string $ipsetName): void - { - $this->firewallRepository->setServer($server); - - $this->firewallRepository->createIpset($ipsetName); - - foreach ($addresses as $address) { - $this->firewallRepository->lockIp($ipsetName, $address); - } - } - - public function getMacAddresses(Server $server, bool $eloquent = true, bool $proxmox = false): MacAddressData - { - if ($eloquent) { - $addresses = $this->getAddresses($server); - - $eloquentMacAddress = $addresses->ipv4->first() - ?->mac_address ?? $addresses->ipv6->first()?->mac_address; - } - - if ($proxmox) { - $config = $this->cloudinitRepository->setServer($server)->getConfig(); - - $proxmoxMacAddress = null; - if (preg_match( - "/\b[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}:[[:xdigit:]]{2}\b/su", - Arr::get($config, 'net0', ''), - $matches, - )) { - $proxmoxMacAddress = $matches[0]; - } - } - - return MacAddressData::from([ - 'eloquent' => $eloquentMacAddress ?? null, - 'proxmox' => $proxmoxMacAddress ?? null, - ]); - } - - public function getAddresses(Server $server): ServerAddressesData - { - return ServerAddressesData::from([ - 'ipv4' => array_values( - $server->addresses->where('type', AddressType::IPV4->value)->toArray(), - ), - 'ipv6' => array_values( - $server->addresses->where('type', AddressType::IPV6->value)->toArray(), - ), - ]); - } - - public function syncSettings(Server $server): void - { - $macAddresses = $this->getMacAddresses($server, true, true); - $addresses = $this->getAddresses($server); - - $this->clearIpsets($server); - $this->cloudinitService->updateIpConfig($server, CloudinitAddressConfigData::from([ - 'ipv4' => $addresses->ipv4->first()?->toArray(), - 'ipv6' => $addresses->ipv6->first()?->toArray(), - ])); - $this->lockIps( - $server, - array_unique(Arr::flatten($server->addresses()->get(['address'])->toArray())), - 'ipfilter-net0', - ); - $this->firewallRepository->setServer($server)->updateOptions([ - 'enable' => true, - 'ipfilter' => true, - 'policy_in' => 'ACCEPT', - 'policy_out' => 'ACCEPT', - ]); - - $macAddress = $macAddresses->eloquent ?? $macAddresses->proxmox; - $this->ensureNet0BaseConfig($server, $macAddress); - } - - public function updateRateLimit(Server $server, ?int $mebibytes = null): void - { - $macAddresses = $this->getMacAddresses($server, true, true); - $macAddress = $macAddresses->eloquent ?? $macAddresses->proxmox; - - $rawConfig = $this->allocationRepository->setServer($server)->getConfig(); - $networkConfig = collect($rawConfig)->where('key', '=', 'net0')->first(); - - if (is_null($networkConfig)) { - return; - } - - $parsedConfig = $this->parseConfig($networkConfig['value']); - - $this->applyBaseNet0Fields($parsedConfig, $server, $macAddress); - - if (is_null($mebibytes)) { - $parsedConfig = array_values( - array_filter($parsedConfig, fn ($item) => $item->key !== 'rate') - ); - } else { - $this->setConfigField($parsedConfig, 'rate', $mebibytes, 'rate'); - } - - $newConfig = implode(',', array_map(fn ($item) => "{$item->key}={$item->value}", $parsedConfig)); - - if ( - $this->normalizeNetConfigForComparison($networkConfig['value']) === - $this->normalizeNetConfigForComparison($newConfig) - ) { - return; - } - - $this->allocationRepository->setServer($server)->update(['net0' => $newConfig]); - } - - public function updateAddresses(Server $server, array $addressIds): void - { - $currentAddresses = $server->addresses()->get()->pluck('id')->toArray(); - - $addressesToAdd = array_diff($addressIds, $currentAddresses); - $addressesToRemove = array_filter( - $currentAddresses, - fn ($id) => !in_array($id, $addressIds), - ); - - if (!empty($addressesToAdd)) { - $this->repository->attachAddresses($server, $addressesToAdd); - } - - if (!empty($addressesToRemove)) { - Address::query() - ->where('server_id', $server->id) - ->whereIn('id', $addressesToRemove) - ->update(['server_id' => null]); - } - } - - private function ensureNet0BaseConfig(Server $server, string $macAddress): void - { - $rawConfig = $this->allocationRepository->setServer($server)->getConfig(); - $net0 = collect($rawConfig)->where('key', '=', 'net0')->first(); - $parsedConfig = $net0 ? $this->parseConfig($net0['value']) : []; - - $this->applyBaseNet0Fields($parsedConfig, $server, $macAddress); - - $newConfig = implode(',', array_map(fn ($item) => "{$item->key}={$item->value}", $parsedConfig)); - - if ($net0 && $this->normalizeNetConfigForComparison($net0['value']) === $this->normalizeNetConfigForComparison($newConfig)) { - return; - } - - $this->allocationRepository->setServer($server)->update(['net0' => $newConfig]); - } - - private function applyBaseNet0Fields(array &$parsedConfig, Server $server, string $macAddress): void - { - $this->setConfigField($parsedConfig, self::NIC_MODELS, $macAddress, 'virtio'); - $this->setConfigField($parsedConfig, 'bridge', $server->node->network, 'bridge'); - $this->setConfigField($parsedConfig, 'firewall', 1, 'firewall'); - } - - private function setConfigField(array &$parsedConfig, string|array $keys, mixed $value, string $defaultKey): void - { - $keys = (array) $keys; - foreach ($parsedConfig as $item) { - if (in_array($item->key, $keys, true)) { - $item->value = $value; - return; - } - } - $parsedConfig[] = (object) ['key' => $defaultKey, 'value' => $value]; - } - - private function normalizeNetConfigForComparison(string $config): array - { - $normalized = []; - foreach ($this->parseConfig($config) as $item) { - $key = strtolower(trim((string) $item->key)); - $value = trim((string) $item->value); - - if (preg_match('/^(?:[0-9a-f]{2}:){5}[0-9a-f]{2}$/i', $value)) { - $value = strtolower($value); - } - - $normalized[$key] = $value; - } - - ksort($normalized); - - return $normalized; - } - - private function parseConfig(string $config): array - { - $parsedObjects = []; - - foreach (explode(',', $config) as $component) { - $component = trim($component); - if ($component === '') { - continue; - } - - [$key, $value] = array_pad(explode('=', $component, 2), 2, ''); - $parsedObjects[] = (object) ['key' => $key, 'value' => $value]; - } - - return $parsedObjects; - } -} diff --git a/app/Services/Servers/OveragePenaltyResolver.php b/app/Services/Servers/OveragePenaltyResolver.php new file mode 100644 index 00000000000..56cda5b261e --- /dev/null +++ b/app/Services/Servers/OveragePenaltyResolver.php @@ -0,0 +1,37 @@ + per-node override -> global BandwidthSettings. + * Single source of truth so enforcement, the "effective value" UI hint, and + * tests all agree. See docs/bandwidth-rate-limiting-plan.md §5.2. + */ +class OveragePenaltyResolver +{ + public function __construct(private BandwidthSettings $settings) {} + + public function for(Server $server): OveragePenaltyData + { + return $server->overage_penalty + ?? $server->node->overage_penalty + ?? $this->global(); + } + + /** + * The global-tier default, materialized from the panel settings. + */ + public function global(): OveragePenaltyData + { + return new OveragePenaltyData( + action: OveragePenaltyAction::from($this->settings->overage_action), + rate: $this->settings->overage_rate, + ); + } +} diff --git a/app/Services/Servers/Power/ServerPowerLockService.php b/app/Services/Servers/Power/ServerPowerLockService.php new file mode 100644 index 00000000000..3707fedde51 --- /dev/null +++ b/app/Services/Servers/Power/ServerPowerLockService.php @@ -0,0 +1,217 @@ +id}:power-action"; + } + + public function resultKey(Server $server): string + { + return "server:{$server->id}:power-action:result"; + } + + /** + * Atomically claim the lock for $command. Throws if another power action is + * already in flight for this server. + * + * The task UPID isn't known yet — Proxmox only returns it once the command + * is sent — so it is attached afterwards by attachTask(). The claim has to + * happen first, before touching Proxmox, or two requests could both send. + * + * @throws PowerActionInProgressException + */ + public function acquire(Server $server, PowerCommand $command): PendingPowerActionData + { + $pending = new PendingPowerActionData($command, now()->toIso8601String()); + + $acquired = Cache::add($this->key($server), [ + 'action' => $pending->toArray(), + 'upid' => null, + ], self::TTL_SECONDS); + + if (! $acquired) { + throw new PowerActionInProgressException; + } + + // A new action supersedes the previous one's outcome; drop it so a stale + // success/failure can't sit alongside the action now in flight. + Cache::forget($this->resultKey($server)); + + return $pending; + } + + /** + * Record the Proxmox task the sent command spawned, so resolve() can watch + * it to completion. A no-op if the lock is already gone (released on a send + * failure, or expired) — there is nothing to attach to. + */ + public function attachTask(Server $server, ?string $upid): void + { + $record = Cache::get($this->key($server)); + + if (! $record) { + return; + } + + Cache::put( + $this->key($server), + [...$record, 'upid' => $upid], + self::TTL_SECONDS, + ); + } + + public function pending(Server $server): ?PendingPowerActionData + { + $record = Cache::get($this->key($server)); + + return $record ? $this->action($record) : null; + } + + /** + * Reconcile the held lock against the Proxmox task the command spawned, + * releasing it once that task has finished. + * + * Returns the action still in flight, or null once nothing is pending — + * which is what the state endpoints hand back to the UI. A finished task + * releases the lock whether it succeeded or failed: either way the attempt + * is over, and a failed one (a shutdown the guest refused) should stop + * reading as "in progress". + */ + public function resolve(Server $server): ?PendingPowerActionData + { + $record = Cache::get($this->key($server)); + + if (! $record) { + return null; + } + + $pending = $this->action($record); + $upid = $record['upid'] ?? null; + + // No task to watch — a command that returned no UPID, or a record left + // by an older release. The TTL is the only way out. + if (! is_string($upid)) { + return $pending; + } + + try { + $task = $this->activity->setNode($server->node)->getStatus($upid); + } catch (\Throwable) { + // Proxmox is unreachable or has already rotated the task out of its + // log. Don't fail the state read over it — leave the lock in place + // and let the TTL clear it. + return $pending; + } + + // Still running: keep the controls locked. + if ($task->status === TaskStatus::RUNNING) { + return $pending; + } + + // Finished (succeeded or failed): record the outcome for the UI to pick + // up, then release so the controls unlock on the next poll. + $this->recordResult($server, $pending, $task); + $this->release($server); + + return null; + } + + /** + * The outcome of the most recently finished action, or null once it has + * expired (or none has completed since the last acquire()). + */ + public function result(Server $server): ?PowerActionResultData + { + $record = Cache::get($this->resultKey($server)); + + return $record ? PowerActionResultData::from($record) : null; + } + + public function release(Server $server): void + { + Cache::forget($this->key($server)); + } + + /** + * Persist a finished task's outcome under the result key. `exitStatus` is + * "OK"/"WARNINGS" on success and Proxmox's raw error string on failure; a + * task that reports no exit status at all is treated as a plain success. + */ + private function recordResult(Server $server, PendingPowerActionData $pending, TaskData $task): void + { + $exit = $task->exitStatus; + + $ok = $exit === null + || $exit === TaskExitStatus::OK + || $exit === TaskExitStatus::WARNINGS; + + $exitStatus = $exit instanceof TaskExitStatus ? $exit->value : $exit; + + $result = new PowerActionResultData( + command: $pending->command, + requestedAt: $pending->requestedAt, + ok: $ok, + exitStatus: $exitStatus, + ); + + Cache::put($this->resultKey($server), $result->toArray(), self::RESULT_TTL_SECONDS); + } + + /** + * The action out of a cache record. Falls back to reading the record itself + * as the action so a lock written by an older release — which stored the + * bare action, with no wrapper around it — is still understood for the + * minute it takes to expire. + */ + private function action(array $record): PendingPowerActionData + { + return PendingPowerActionData::from($record['action'] ?? $record); + } +} diff --git a/app/Services/Servers/SendServerPowerCommand.php b/app/Services/Servers/SendServerPowerCommand.php new file mode 100644 index 00000000000..330dbfcbca5 --- /dev/null +++ b/app/Services/Servers/SendServerPowerCommand.php @@ -0,0 +1,54 @@ +lock->acquire($server, $command); + + try { + $upid = $this->client->setServer($server)->send($command); + } catch (Throwable $e) { + // The command never landed — free the lock so the user can retry + // immediately rather than waiting out the TTL. + $this->lock->release($server); + + throw $e; + } + + // Record the task the command spawned so the lock clears when Proxmox + // reports it finished, rather than only when the TTL fires. + $this->lock->attachTask($server, is_string($upid) ? $upid : null); + } +} diff --git a/app/Services/Servers/SerialConsoleService.php b/app/Services/Servers/SerialConsoleService.php new file mode 100644 index 00000000000..df39fa534ff --- /dev/null +++ b/app/Services/Servers/SerialConsoleService.php @@ -0,0 +1,100 @@ +configClient->setServer($server)->getPendingConfig(); + + foreach ($rows as $row) { + if (($row['key'] ?? null) !== self::DEVICE) { + continue; + } + + // `value` is what the running guest has; `pending` is what it will + // have at next boot. A row with only the latter is the mid-state + // between enabling and restarting. + $live = ($row['value'] ?? '') !== ''; + $queued = ($row['pending'] ?? '') !== ''; + + return new SerialConsoleData( + enabled: $live, + restartRequired: ! $live && $queued, + ); + } + + return new SerialConsoleData(enabled: false, restartRequired: false); + } + + /** + * Add the serial device, unless the VM already has one. + * + * @throws RequestException + * @throws ConnectionException + */ + public function enable(Server $server): SerialConsoleData + { + $status = $this->status($server); + + if ($status->enabled || $status->restartRequired) { + return $status; + } + + $this->configClient->setServer($server)->update([ + self::DEVICE => self::MODE, + ]); + + return $this->status($server); + } + + /** + * Add the serial device to a config payload when the VM has none. + * + * Called from the deploy-time sync so servers built from here on out have a + * working terminal console without anyone being told to go and add one. + * + * @param array $payload + * @return array + */ + public function withDevice(array $payload, bool $alreadyPresent): array + { + if ($alreadyPresent) { + return $payload; + } + + return [...$payload, self::DEVICE => self::MODE]; + } +} diff --git a/app/Services/Servers/ServerAuthService.php b/app/Services/Servers/ServerAuthService.php index cac708546eb..18e1dd18c1b 100644 --- a/app/Services/Servers/ServerAuthService.php +++ b/app/Services/Servers/ServerAuthService.php @@ -1,53 +1,39 @@ configRepository->setServer($server)->update(['cipassword' => $password]); - - try { - $osInfo = $this->guestAgentRepository->setServer($server)->guestAgentOs(); - - // If we have valid OS info, decide which username to use - if (is_array($osInfo) && isset($osInfo['result']['name'])) { - $osName = $osInfo['result']['name']; - $username = Str::contains(Str::lower($osName), 'windows') ? 'Administrator' : 'root'; - - $this->guestAgentRepository - ->setServer($server) - ->updateGuestAgentPassword($username, $password); - } - } catch (\Exception $e) { - // Optionally log or handle exceptions - } + // Cloudinit now applies passwords on every supported OS (Windows included), so it's the + // single source of truth here. The old QEMU-guest-agent live-set path (v4) was a more + // fragile duplicate — it needed the agent running and OS-specific usernames — and is + // deliberately not carried onto next. + $this->configClient->setServer($server)->update(['cipassword' => $password]); } - public function getSSHKeys(Server $server): string + public function getSSHKeys(Server $server): array { - $raw = collect($this->configRepository->setServer($server)->getConfig())->where('key', '=', 'sshkeys')->first()['value'] ?? ''; + $raw = collect($this->configClient->setServer($server)->getConfig())->where('key', '=', 'sshkeys')->first()['value'] ?? ''; - return rawurldecode($raw); + return array_values(array_filter( + explode("\n", rawurldecode($raw)), + fn (string $key) => trim($key) !== '', + )); } - public function updateSSHKeys(Server $server, ?string $keys): void + public function setSSHKeys(Server $server, ?string $keys): void { if (! empty($keys)) { - $this->configRepository->setServer($server)->update(['sshkeys' => rawurlencode($keys)]); + $this->configClient->setServer($server)->update(['sshkeys' => rawurlencode($keys)]); } else { - $this->configRepository->setServer($server)->update(['delete' => 'sshkeys']); + $this->configClient->setServer($server)->update(['delete' => 'sshkeys']); } } } diff --git a/app/Services/Servers/ServerBuildDispatchService.php b/app/Services/Servers/ServerBuildDispatchService.php deleted file mode 100644 index 42a6357f2a0..00000000000 --- a/app/Services/Servers/ServerBuildDispatchService.php +++ /dev/null @@ -1,108 +0,0 @@ -getChainedBuildJobs($deployment); - - Bus::chain($jobs) - ->catch(fn () => $deployment->server->update(['status' => Status::INSTALL_FAILED->value])) - ->dispatch(); - - $deployment->server->update(['status' => Status::INSTALLING->value]); - } - - /* the delete virtual machine method is typically not used by itself and is accompanied by other logic like server reinstallations, server deletions */ - public function delete(Server $server): void - { - $jobs = $this->getChainedDeleteJobs($server); - - Bus::chain($jobs) - ->dispatch(); - } - - public function rebuild(ServerDeploymentData $deployment): void - { - $jobs = [ - ...$this->getChainedDeleteJobs($deployment->server), - ...$this->getChainedBuildJobs($deployment), - ]; - - Bus::chain($jobs) - ->catch(fn () => $deployment->server->update(['status' => Status::INSTALL_FAILED->value])) - ->dispatch(); - - $deployment->server->update(['status' => Status::INSTALLING->value]); - } - - private function getChainedBuildJobs(ServerDeploymentData $deployment): array - { - // Base jobs: either create a new server or sync an existing one - $jobs = $deployment->should_create_server - ? [ - new BuildServerJob($deployment->server->id, $deployment->template->id), - new WaitUntilVmIsCreatedJob($deployment->server->id), - new SyncBuildJob($deployment->server->id), - ] - : [ - new SyncBuildJob($deployment->server->id), - ]; - - if (Str::contains(Str::lower($deployment->template->name), 'windows')) { - $jobs = [ - ...$jobs, - new SendPowerCommandJob($deployment->server->id, PowerAction::START), - new MonitorStateJob($deployment->server->id, State::RUNNING), - ]; - - if (! empty($deployment->account_password)) { - $jobs[] = new UpdatePasswordJob($deployment->server->id, $deployment->account_password); - } - } else { - // For non-Windows, update password first if provided - if (! empty($deployment->account_password)) { - $jobs[] = new UpdatePasswordJob($deployment->server->id, $deployment->account_password); - } - // Then power on if user wants to start on completion - if ($deployment->start_on_completion) { - $jobs[] = new SendPowerCommandJob($deployment->server->id, PowerAction::START); - } - } - - // Final callback to clear the status - $jobs[] = function () use ($deployment) { - Server::findOrFail($deployment->server->id)->update(['status' => null]); - }; - - return $jobs; - } - - public function getChainedDeleteJobs(Server $server): array - { - return [ - new SendPowerCommandJob($server->id, PowerAction::KILL), - new MonitorStateJob($server->id, State::STOPPED), - new DeleteServerJob($server->id), - new WaitUntilVmIsDeletedJob($server->id), - ]; - } -} diff --git a/app/Services/Servers/ServerBuildService.php b/app/Services/Servers/ServerBuildService.php index a17fb522b1d..df39fd8050d 100644 --- a/app/Services/Servers/ServerBuildService.php +++ b/app/Services/Servers/ServerBuildService.php @@ -1,59 +1,187 @@ serverRepository->setServer($server)->delete(); + return $this->serverClient->setServer($server)->delete(); } - public function build(Server $server, Template $template) + /** + * @return string Job UPID + * + * @throws RequestException + * @throws ConnectionException + */ + public function build(Server $server, ImageVersion $version, array $volids): string { - $this->serverRepository->setServer($server)->create($template); + return $this->serverClient->setServer($server)->create($version, $volids); } + /** + * @throws RequestException + * @throws ConnectionException + */ public function isVmCreated(Server $server): bool { - try { - $config = collect($this->configRepository->setServer($server)->getConfig()); + $servers = $this->resourceClient->setServer($server)->getResources(); + + // The import holds a `create` lock rather than a `clone` one. Reading + // the wrong lock would report the VM ready while Proxmox was still + // writing its disk, and every step after this assumes a finished guest. + $vm = $servers->where('vmid', $server->vmid) + ->where('lockStatus', '!=', ProxmoxLock::CREATE) + ->first(); + + if ($vm) { + return true; + } - $lock = $config->where('key', '=', 'lock')->first(); + return false; + } + + /** + * Byte progress of an import, read from the task log. + * + * Proxmox reports a disk import the way it reported a clone -- one + * `transferred X of Y` line per drive, rewritten as it goes -- so the + * aggregation is unchanged; only the line that opens a new drive differs. + * Both openers are matched because a node mid-upgrade can emit either, and + * an unrecognised log costs a progress bar rather than a build: completion + * is decided by the guest's lock state, never by this. + * + * @param string $upid The unique process ID for the task. + * @return array [int, int] Current and total bytes. + * + * @throws ConnectionException + * @throws RequestException + */ + public function getImportProgress(Node $node, string $upid): array + { + // Get logs in chronological order to correctly track the context of each clone operation. + $logs = $this->activityClient->setNode($node)->getLogsByTask(upid: $upid, limitLinesTo: 1000); - if ($lock && ($lock['value'] === 'clone' || $lock['value'] === 'create')) { - return false; + $progressPerDisk = []; + $currentDiskId = null; + + // Regex to identify the start of a new disk clone and capture its unique identifier. + $diskIdRegex = '/(?:create full clone of drive|importing disk .* to) .*\((.*)\)/'; + // Regex to capture the current and total transferred data from a progress line. + $progressRegex = '/transferred\s+([\d.]+)\s+([A-Za-z]+)\s+of\s+([\d.]+)\s+([A-Za-z]+)/'; + + foreach ($logs as $log) { + $line = $log->text; + // Check if a new disk clone operation has started. + if (preg_match($diskIdRegex, $line, $matches)) { + $currentDiskId = $matches[1]; + // Initialize progress for this new disk if we haven't seen it before. + if (! isset($progressPerDisk[$currentDiskId])) { + $progressPerDisk[$currentDiskId] = ['current' => 0, 'total' => 0]; + } + } + + // If we are within the context of a specific disk clone, look for progress lines. + if ($currentDiskId && preg_match($progressRegex, $line, $matches)) { + $currentValue = (float) $matches[1]; + $currentUnit = $matches[2]; + $totalValue = (float) $matches[3]; + $totalUnit = $matches[4]; + + // Update the latest progress for the current disk. + // As we iterate, this will be overwritten until we have the final value for this disk. + $progressPerDisk[$currentDiskId] = [ + 'current' => ByteUnit::fromIec($currentUnit)?->toBytes($currentValue) ?? 0, + 'total' => ByteUnit::fromIec($totalUnit)?->toBytes($totalValue) ?? 0, + ]; } - } catch (ProxmoxConnectionException $e) { - return false; } - return true; + $total = 0; + $current = 0; + + // Sum up the final progress from all disk operations found in the logs. + foreach ($progressPerDisk as $progress) { + $total += $progress['total']; + $current += $progress['current']; + } + + return [$current, $total]; + } + + /** + * Byte progress of an image download onto a node. + * + * Separate from the import because it is a storage task with a different + * log, and deliberately tolerant: several shapes of progress line are + * accepted and an unrecognised one simply yields no reading. The fetch step + * finishes when the file is actually on the node, so a log this cannot + * parse costs the bar its movement and nothing else. + * + * @return array [int, int] Current and total bytes; [0, 0] when unreadable. + * + * @throws ConnectionException + * @throws RequestException + */ + public function getDownloadProgress(Node $node, string $upid): array + { + $logs = $this->activityClient->setNode($node)->getLogsByTask(upid: $upid, limitLinesTo: 1000); + + $current = 0; + $total = 0; + + foreach ($logs as $log) { + if (preg_match('/([\d.]+)\s*([KMGT]i?B)\s+of\s+([\d.]+)\s*([KMGT]i?B)/i', $log->text, $matches)) { + $current = ByteUnit::fromIec($matches[2])?->toBytes((float) $matches[1]) ?? $current; + $total = ByteUnit::fromIec($matches[4])?->toBytes((float) $matches[3]) ?? $total; + } + } + + return [$current, $total]; } + /** + * @throws RequestException + * @throws ConnectionException + */ public function isVmDeleted(Server $server): bool { - try { - $this->configRepository->setServer($server)->getConfig(); - } catch (ProxmoxConnectionException $e) { - return true; + $servers = $this->resourceClient->setServer($server)->getResources(); + + $vm = $servers->where('vmid', $server->vmid)->first(); + + if ($vm) { + return false; } - return false; + return true; } } diff --git a/app/Services/Servers/ServerConsoleService.php b/app/Services/Servers/ServerConsoleService.php deleted file mode 100644 index dcb5cf4b8f4..00000000000 --- a/app/Services/Servers/ServerConsoleService.php +++ /dev/null @@ -1,60 +0,0 @@ -accessRepository->setServer($server); - $this->serverRepository->setServer($server); - - $user = $this->accessRepository->createUser(CreateUserData::from([ - 'realm_type' => 'pve', - 'enabled' => true, - 'expires_at' => now()->addDay(), - ])); - - try { - $this->accessRepository->createRole('convoy-console', 'VM.Audit,VM.Console'); - } catch (Exception) { - } - - $this->serverRepository->addUser( - RealmType::PVE, - $user->username, - 'convoy-console' - ); - - return $this->accessRepository->createUserCredentials(RealmType::PVE, $user->username, $user->password); - } - - public function createNoVncCredentials(Server $server): NoVncCredentialsData - { - $credentials = $this->createConsoleUserCredentials($server); - - return $this->consoleRepository->setServer($server)->createNoVncCredentials($credentials); - } - - public function createXTermjsCredentials(Server $server): XTermCredentialsData - { - $credentials = $this->createConsoleUserCredentials($server); - - return $this->consoleRepository->setServer($server)->createXTermjsCredentials($credentials); - } -} diff --git a/app/Services/Servers/ServerCreationService.php b/app/Services/Servers/ServerCreationService.php index 8c59d0743ba..7b5ed1bc2c0 100644 --- a/app/Services/Servers/ServerCreationService.php +++ b/app/Services/Servers/ServerCreationService.php @@ -1,17 +1,32 @@ generateUniqueUuidCombo(); + $node = Node::find($data['node_id']); + + $addresses = collect(); + if (Arr::has($data, 'limits.addresses') && ! empty(Arr::get($data, 'limits.addresses'))) { + $addresses = Address::findMany(Arr::get($data, 'limits.addresses'))->load('addressBlock'); + } else { + $ipv4Count = (int) Arr::get($data, 'limits.addresses_ipv4_count', 0); + $ipv6Count = (int) Arr::get($data, 'limits.addresses_ipv6_count', 0); + if ($ipv4Count > 0 || $ipv6Count > 0) { + $addresses = $this->addressAllocationService->handle($data['limits']['network_interface_id'], $ipv4Count, $ipv6Count); + } + } - public function handle(array $data) - { - $uuid = $this->generateUniqueUuidCombo(); - - $shouldCreateServer = Arr::get($data, 'should_create_server'); - $template = $shouldCreateServer ? Template::where( - 'uuid', '=', Arr::get($data, 'template_uuid'), - )->firstOrFail() : null; - - if ($template) { - if ($template->group->node_id !== intval(Arr::get($data, 'node_id'))) { - throw new InvalidTemplateException( - 'This template is inaccessible to the specified node', - ); + // forceCreate (not create): uuid / uuid_short are $guarded, so plain + // mass-assignment silently drops them and the NOT NULL uuid column + // blows up. forceCreate assigns them while unguarded; save-time + // validation is unchanged. + $server = Server::forceCreate([ + 'uuid' => $uuid, + 'uuid_short' => substr($uuid, 0, 8), + 'user_id' => $data['user_id'], + 'node_id' => $node->id, + 'network_interface_id' => Arr::get($data, 'limits.network_interface_id'), + 'storage_id' => $data['storage_id'], + 'vmid' => $data['vmid'] ?? $this->generateUniqueVmId($node), + 'hostname' => $data['hostname'], + 'name' => $data['name'], + 'description' => Arr::get($data, 'description'), + 'lifecycle' => $data['deferred_os_selection'] ? ServerLifecycle::DEFERRED_OS_SELECTION : ServerLifecycle::INSTALLING, + 'cpu' => $data['limits']['cpu'], + 'memory' => $data['limits']['memory'], + 'disk' => $data['limits']['disk'], + 'primary_ipv4_address_id' => $addresses->firstWhere('version', AddressVersion::IPv4)?->id, + 'primary_ipv6_address_id' => $addresses->firstWhere('version', AddressVersion::IPv6)?->id, + 'backup_count_limit' => Arr::get($data, 'limits.backups.count'), + 'backup_size_limit' => Arr::get($data, 'limits.backups.size'), + 'bandwidth_limit' => Arr::get($data, 'limits.bandwidth'), + 'speed_limit' => Arr::get($data, 'limits.speed_limit'), + // Anchor the monthly quota reset to today's day-of-month; a seam + // Paymenter can later point at the real renewal date (see the plan §6). + 'bandwidth_reset_day' => now()->day, + 'vlan_tag' => Arr::get($data, 'limits.vlan_tag'), + ]); + + // Mirror the primary disk into server_disks. Expand-first: the + // servers.(storage_id, disk) columns remain authoritative for the + // clone; this row is what the disk-oriented usage aggregation and + // (later) secondary disks build on. + $server->disks()->create([ + 'storage_id' => $server->storage_id, + 'size' => $data['limits']['disk'], + 'interface' => null, + 'is_primary' => true, + 'disk_index' => 0, + ]); + + // Secondary/data disks, each on its own storage. interface is null + // until the build allocates them (AllocationService::syncDisks). + foreach (array_values(Arr::get($data, 'limits.disks', [])) as $index => $disk) { + $server->disks()->create([ + 'storage_id' => $disk['storage_id'], + 'size' => $disk['size'], + 'interface' => null, + 'is_primary' => false, + 'disk_index' => $index + 1, + ]); } - } - $nodeId = Arr::get($data, 'node_id'); - - $server = Server::create([ - 'uuid' => $uuid, - 'uuid_short' => substr($uuid, 0, 8), - 'status' => $shouldCreateServer ? Status::INSTALLING->value : null, - 'name' => Arr::get($data, 'name'), - 'user_id' => Arr::get($data, 'user_id'), - 'node_id' => $nodeId, - 'vmid' => Arr::get($data, 'vmid') ?? $this->generateUniqueVmId($nodeId), - 'hostname' => Arr::get($data, 'hostname'), - 'cpu' => Arr::get($data, 'limits.cpu'), - 'memory' => Arr::get($data, 'limits.memory'), - 'disk' => Arr::get($data, 'limits.disk'), - 'snapshot_limit' => Arr::get($data, 'limits.snapshots'), - 'backup_limit' => Arr::get($data, 'limits.backups'), - 'bandwidth_limit' => Arr::get($data, 'limits.bandwidth'), - ]); - - $server->refresh(); - - $deployment = ServerDeploymentData::from([ - 'server' => $server, - 'template' => $template, - 'account_password' => Arr::get($data, 'account_password'), - 'should_create_server' => $shouldCreateServer, - 'start_on_completion' => Arr::get($data, 'start_on_completion'), - ]); - - if ($addressIds = Arr::get($data, 'limits.address_ids')) { - $this->networkService->updateAddresses($server, $addressIds); - } + if ($addresses->isNotEmpty()) { + $this->networkService->syncAddresses($server, $addresses->pluck('id')->all()); + } - $this->buildDispatchService->build($deployment); + if (! $data['deferred_os_selection']) { + $definition = filled($imageUuid = Arr::get($data, 'image_uuid')) + ? ImageDefinition::where('uuid', $imageUuid)->first() + : null; + + $deployment = $server->deployments()->create([ + // Both are recorded: the definition is what was chosen, the + // version is what the server was actually built from. A + // later rebuild of that image cannot rewrite this answer. + 'image_definition_id' => $definition?->id, + 'image_version_id' => $definition?->latestVersion()?->id, + 'type' => $data['should_create_vm'] ? DeploymentType::INSTALL : DeploymentType::IMPORT, + 'status' => DeploymentStatus::PENDING, + 'start_on_completion' => $data['start_on_completion'], + 'requested_at' => now(), + ]); + + $this->buildServerAction->execute($deployment, Arr::get($data, 'account_password')); + } - return $server; + return $server; + }); } - public function generateUniqueVmId(int $nodeId): int + /** + * @throws NoUniqueVmidException + * @throws NextVMIDRetrievalException + */ + public function generateUniqueVmId(Node $node): int { - $vmid = random_int(100, 999999999); + $vmid = $this->allocationClient->setNode($node)->getNextVMID(); $attempts = 0; - while (!$this->repository->isUniqueVmId($nodeId, $vmid)) { - $vmid = random_int(100, 999999999); + while (true) { + // Check uniqueness in our database + if (Server::isUniqueVmId($node, $vmid)) { + // Check uniqueness in Proxmox + if ($this->allocationClient->isVMIDAvailable($vmid)) { + break; + } + + $vmid++; + } else { + $vmid++; + } if ($attempts++ > 10) { - throw new NoUniqueVmidException(); + throw new NoUniqueVmidException; } } return $vmid; } + /** + * @throws NoUniqueUuidComboException + */ public function generateUniqueUuidCombo(): string { $uuid = Str::uuid()->toString(); $short = substr($uuid, 0, 8); $attempts = 0; - while (!$this->repository->isUniqueUuidCombo($uuid, $short)) { + while (! Server::isUniqueUuidCombo($uuid, $short)) { $uuid = Str::uuid()->toString(); $short = substr($uuid, 0, 8); if ($attempts++ > 10) { - throw new NoUniqueUuidComboException(); + throw new NoUniqueUuidComboException; } } diff --git a/app/Services/Servers/ServerDeletionService.php b/app/Services/Servers/ServerDeletionService.php index ff42bf91437..a4313cc13ba 100644 --- a/app/Services/Servers/ServerDeletionService.php +++ b/app/Services/Servers/ServerDeletionService.php @@ -1,53 +1,47 @@ validateStatus($server); - $server->update(['status' => Status::DELETING->value]); - - if (! $noPurge) { - Bus::chain([ - new PurgeBackupsJob($server->id), - ...$this->buildDispatchService->getChainedDeleteJobs($server), - function () use ($server) { - Server::findOrFail($server->id)->delete(); - }, - ]) - ->catch(fn () => $server->update(['status' => Status::DELETION_FAILED->value])) - ->dispatch(); + if ($noPurge) { + $server->delete(); return; } - $server->delete(); + $deployment = $server->deployments()->create([ + 'type' => DeploymentType::DELETE, + 'status' => DeploymentStatus::PENDING, + 'start_on_completion' => false, + 'requested_at' => now(), + ]); + + $this->deleteServerAction->execute($deployment); } - public function validateStatus(Server $server, bool $verifyStatusOnly = false) + public function validateStatus(Server $server, bool $verifyStatusOnly = false): void { - if ( - ! is_null($server->status) && $server->status !== Status::DELETING->value - ) { - throw new ServerStatusConflictException($server); + if ($server->lifecycle !== ServerLifecycle::DELETING) { + throw new ServerUnavailableException($server); } if (! $verifyStatusOnly) { if ($server->backups()->whereNull('completed_at')->exists()) { - throw new ServerStatusConflictException($server); + throw new ServerUnavailableException($server); } } } diff --git a/app/Services/Servers/ServerDetailService.php b/app/Services/Servers/ServerDetailService.php deleted file mode 100644 index cb6f4f46db7..00000000000 --- a/app/Services/Servers/ServerDetailService.php +++ /dev/null @@ -1,67 +0,0 @@ -networkService->getAddresses($server); - - return ServerEloquentData::from([ - 'id' => $server->id, - 'uuid_short' => $server->uuid_short, - 'uuid' => $server->uuid, - 'node_id' => $server->node_id, - 'hostname' => $server->hostname, - 'name' => $server->name, - 'description' => $server->description, - 'status' => $server->status, - 'usages' => [ - 'bandwidth' => $server->bandwidth_usage, - ], - 'limits' => [ - 'cpu' => $server->cpu, - 'memory' => $server->memory, - 'disk' => $server->disk, - 'snapshots' => $server->snapshot_limit, - 'backups' => $server->backup_limit, - 'bandwidth' => $server->bandwidth_limit, - 'addresses' => $addresses, - 'mac_address' => $this->networkService->getMacAddresses($server)->eloquent, - ], - ]); - } - - public function getByProxmox(Server $server): ServerProxmoxData - { - $server = $server->loadMissing(['addresses', 'node']); - - $resources = $this->allocationRepository->setServer($server)->getResources(); - - return ServerProxmoxData::from([ - 'id' => $server->id, - 'uuid_short' => $server->uuid_short, - 'uuid' => $server->uuid, - 'node_id' => $server->node_id, - 'state' => Arr::get($resources, 'status'), - 'locked' => Arr::get($resources, 'lock', false), - 'config' => [ - 'mac_address' => $this->networkService->getMacAddresses($server, false, true)->proxmox, - 'boot_order' => $this->allocationService->getBootOrder($server), - 'disks' => $this->allocationService->getDisks($server), - /* 'addresses' => $this->cloudinitService->getIpConfig($server), */ - ], - ]); - } -} diff --git a/app/Services/Servers/ServerFirewallService.php b/app/Services/Servers/ServerFirewallService.php new file mode 100644 index 00000000000..8816bebb100 --- /dev/null +++ b/app/Services/Servers/ServerFirewallService.php @@ -0,0 +1,369 @@ +firewallClient->setServer($server)->updateOptions([ + 'enable' => true, + 'ipfilter' => true, + ]); + } + + /** + * @return Collection + * + * @throws RequestException + */ + public function getRules(Server $server): Collection + { + return $this->firewallClient->setServer($server)->getRules(); + } + + /** + * @throws RequestException + */ + public function createRule(Server $server, FirewallRuleData $rule, ?int $position = null): void + { + $this->firewallClient->setServer($server); + + $desiredPosition = $position ?? $this->getRules($server)->count(); + + /* + * Proxmox ignores `pos` on create and always inserts at the top of the + * ruleset -- verified against the live API, where a create sent with + * `pos: 1` still landed at index 0 and pushed the existing rule down. + * + * That default is actively dangerous here: the first matching rule + * wins, so a newly added "allow" would silently override every deny + * rule already in the list. The rule is therefore moved into the + * position the caller asked for straight after it is created. + */ + $this->firewallClient->createRule($rule->toPayload()); + + if ($desiredPosition > 0) { + $this->firewallClient->moveRule(0, $this->toInsertIndex(0, $desiredPosition)); + } + } + + /** + * Translates "the index this rule should end up at" into the index Proxmox + * actually wants. + * + * `moveto` names the slot to insert *before* in the list as it stands + * right now, so a rule travelling downwards has to account for its own + * removal shifting everything above it up by one. Verified live: moving + * index 0 to `moveto: 2` in a three-rule set leaves the rule at index 1. + */ + private function toInsertIndex(int $from, int $to): int + { + return $to > $from ? $to + 1 : $to; + } + + /** + * Replaces the rule at $position. + * + * Fields the caller dropped are named in the request's `delete` list -- + * omitting them would leave the old value in place, and sending them empty + * does not clear them either. + * + * @throws RequestException + */ + public function updateRule( + Server $server, + int $position, + FirewallRuleData $rule, + ?string $digest = null, + ): void { + $this->firewallClient->setServer($server); + + $existing = $this->findRule($server, $position); + $payload = $rule->toPayload(); + $cleared = $rule->clearedKeysAgainst($existing); + + if ($cleared !== []) { + $payload['delete'] = implode(',', $cleared); + } + + if ($digest !== null) { + $payload['digest'] = $digest; + } + + $this->guardAgainstStaleWrite( + fn () => $this->firewallClient->updateRule($position, $payload), + $digest, + ); + } + + /** + * @throws RequestException + */ + public function moveRule( + Server $server, + int $position, + int $newPosition, + ?string $digest = null, + ): void { + // Proves the rule exists before asking Proxmox to move it, so a stale + // index fails as a 404 rather than silently reordering something else. + $this->findRule($server, $position); + + $this->firewallClient->setServer($server); + + $this->guardAgainstStaleWrite( + fn () => $this->firewallClient->moveRule( + $position, + $this->toInsertIndex($position, $newPosition), + $digest, + ), + $digest, + ); + } + + /** + * @throws RequestException + */ + public function deleteRule(Server $server, int $position, ?string $digest = null): void + { + $this->findRule($server, $position); + + $this->firewallClient->setServer($server); + + $this->guardAgainstStaleWrite( + fn () => $this->firewallClient->deleteRule($position, $digest), + $digest, + ); + } + + /** + * @throws RequestException + */ + public function getOptions(Server $server): FirewallOptionsData + { + return $this->firewallClient->setServer($server)->getOptions(); + } + + /** + * Applies the options a user is allowed to change. + * + * `enable` and `ipfilter` are deliberately absent: {@see configureFirewall} + * rewrites both on every network sync, so accepting them here would offer + * a control that silently reverts. + * + * @throws RequestException + */ + public function updateOptions( + Server $server, + FirewallPolicy $inboundPolicy, + FirewallPolicy $outboundPolicy, + FirewallLogLevel $inboundLogLevel, + FirewallLogLevel $outboundLogLevel, + ?string $digest = null, + ): FirewallOptionsData { + $payload = [ + 'policy_in' => $inboundPolicy->value, + 'policy_out' => $outboundPolicy->value, + 'log_level_in' => $inboundLogLevel->value, + 'log_level_out' => $outboundLogLevel->value, + ]; + + if ($digest !== null) { + $payload['digest'] = $digest; + } + + $this->firewallClient->setServer($server); + + $this->guardAgainstStaleWrite( + fn () => $this->firewallClient->updateOptions($payload), + $digest, + ); + + return $this->getOptions($server); + } + + /** + * Runs a write, translating Proxmox's digest refusal into a 409 the client + * can act on. Only meaningful when a digest was actually sent. + * + * @throws ConfigModifiedException + * @throws RequestException + */ + private function guardAgainstStaleWrite(callable $write, ?string $digest): void + { + try { + $write(); + } catch (RequestException $e) { + if ($digest !== null && $this->isConfigModifiedError($e)) { + throw new ConfigModifiedException; + } + + throw $e; + } + } + + /** + * Whether Proxmox rejected the write because the digest no longer matched. + * Same wording as {@see ProxmoxConfigClient}. + */ + private function isConfigModifiedError(RequestException $e): bool + { + return Str::contains( + Str::lower($e->getMessage()), + ['changed by other user', 'modified configuration'], + ); + } + + /** + * @return Collection + * + * @throws RequestException + */ + public function getRefs(Server $server): Collection + { + return $this->firewallClient->setServer($server)->getRefs(); + } + + /** + * @return Collection + * + * @throws RequestException + */ + public function getLog(Server $server, int $start = 0, int $limit = 100): Collection + { + return $this->firewallClient + ->setServer($server) + ->getLog($start, $limit) + // Proxmox returns a single `{"n":1,"t":"no content"}` line rather + // than an empty list when there is nothing to show. Passing that + // through would render the literal words as a log entry. + ->reject(fn (FirewallLogEntryData $entry) => trim($entry->raw) === '' + || strtolower(trim($entry->raw)) === 'no content') + ->values(); + } + + /** + * The cluster's macro list, cached because it only changes with a Proxmox + * upgrade and every rule form asks for it. + * + * @return Collection + * + * @throws RequestException + */ + public function getMacros(Server $server): Collection + { + return Cache::remember( + "nodes.{$server->node_id}.firewall.macros", + now()->addHour(), + fn () => $this->firewallClient->setServer($server)->getMacros(), + ); + } + + /** + * @throws RequestException + */ + private function findRule(Server $server, int $position): FirewallRuleData + { + $rule = $this->getRules($server)->firstWhere('position', $position); + + if (! $rule instanceof FirewallRuleData) { + throw new NotFoundHttpException('Firewall rule not found'); + } + + return $rule; + } + + /** + * Deletes an IP set and unlocks all IP addresses associated with it. + * + * @throws RequestException + */ + public function deleteIpset(Server $server, string|IpsetData $ipset): void + { + $this->firewallClient->setServer($server); + + $this + ->firewallClient + ->getLockedIps($ipset) + ->each(function (LockedIpData $lockedIp) use ($ipset) { + $this->firewallClient->unlockIp($ipset, $lockedIp); + }); + + $this->firewallClient->deleteIpset($ipset); + } + + /** + * Clears all IP sets and unlocks all IP addresses associated with them. + * + * @throws RequestException + */ + public function clearIpsets(Server $server): void + { + $this->firewallClient->setServer($server); + + $this + ->firewallClient + ->getIpsets() + ->each(function (IpsetData $ipset) use ($server) { + $this->deleteIpset($server, $ipset); + }); + } + + /** + * Locks the specified IP addresses in the given IP set. + * + * @throws RequestException + */ + public function lockIps(Server $server, array $addresses, string|IpsetData $ipset): void + { + if ($ipset instanceof IpsetData) { + $ipset = $ipset->name; + } + + $this->firewallClient->setServer($server); + + $this->firewallClient->createIpset($ipset); + + foreach ($addresses as $address) { + $this->firewallClient->lockIp($ipset, $address); + } + } +} diff --git a/app/Services/Servers/ServerNetworkBandwidthService.php b/app/Services/Servers/ServerNetworkBandwidthService.php new file mode 100644 index 00000000000..2ae73a89d19 --- /dev/null +++ b/app/Services/Servers/ServerNetworkBandwidthService.php @@ -0,0 +1,88 @@ +configClient->setServer($server)->getConfig(); + + /** @var array $networkDevices */ + $networkDevices = $config->networkDevices + ->filter(function (NetworkDeviceData $device) use ($rate, $linkDown) { + $rateDiffers = $device->rateLimit !== $rate; + $linkDiffers = $linkDown !== null && (bool) $device->isLinkDown !== $linkDown; + + return $rateDiffers || $linkDiffers; + }) + ->map(function (NetworkDeviceData $device) use ($rate, $linkDown) { + $device->rateLimit = $rate; + + if ($linkDown !== null) { + // false -> null so link_down is omitted rather than emitted as 0. + $device->isLinkDown = $linkDown ?: null; + } + + return $device->toProxmoxString(); + }) + ->reduce(function (array $carry, array $item) { + [$id, $config] = $item; + $carry[$id] = $config; + + return $carry; + }, []); + + // Nothing to change — don't issue a no-op write against Proxmox. + if ($networkDevices === []) { + return; + } + + $this->configClient->update($networkDevices, $config->digest); + } + + /** + * Set the network bandwidth rate limit (bytes/s) on all of the server's NICs, + * leaving link state untouched. + * + * @throws RequestException + * @throws ConfigModifiedException + */ + public function setRateLimit(Server $server, int $rate): void + { + $this->apply($server, $rate); + } + + /** + * Remove the network bandwidth rate limit from all of the server's NICs. + * + * @throws RequestException + * @throws ConfigModifiedException + */ + public function removeRateLimit(Server $server): void + { + $this->apply($server, null); + } +} diff --git a/app/Services/Servers/ServerNetworkService.php b/app/Services/Servers/ServerNetworkService.php new file mode 100644 index 00000000000..0ea5df79b01 --- /dev/null +++ b/app/Services/Servers/ServerNetworkService.php @@ -0,0 +1,198 @@ +flagged_at !== null) { + throw new ServerFlaggedException($server); + } + + $this->firewallService->configureFirewall($server); + $this->firewallService->clearIpsets($server); + $this->lockServerAddresses($server); + + $this->syncCloudinitIpConfig($server); + + $this->syncNetworkDeviceConfig($server); + } + + /** + * @throws RequestException + */ + private function syncNetworkDeviceConfig(Server $server): void + { + $primaryAddresses = $this->getPrimaryAddresses($server); + + $ipv4 = $primaryAddresses->ipv4; + $ipv6 = $primaryAddresses->ipv6; + $macAddress = ($ipv4 instanceof Address ? $ipv4->mac_address : null) + ?? ($ipv6 instanceof Address ? $ipv6->mac_address : null); + $ipv4Interface = $ipv4?->networkInterfaces()->first(); + $ipv6Interface = $ipv6?->networkInterfaces()->first(); + $networkInterface = $server->networkInterface instanceof NetworkInterface + ? $server->networkInterface + : (($ipv4Interface instanceof NetworkInterface ? $ipv4Interface : null) + ?? ($ipv6Interface instanceof NetworkInterface ? $ipv6Interface : null)); + $bridge = $networkInterface?->name; + $hasDesiredVlanTag = $networkInterface instanceof NetworkInterface; + $vlanTag = $networkInterface?->is_vlan_aware + ? ($server->vlan_tag ?? $networkInterface->vlan_tag) + : null; + + $config = $this->configClient->setServer($server)->getConfig(); + + // Skip NICs already in the desired state so we don't rewrite them. + // Firewall isn't the only field we set here — a NIC could be firewalled + // but still need its mac/bridge corrected — so a device is only + // redundant when every managed field would be unchanged. + $devicesToUpdate = $config->networkDevices + ->filter(function (NetworkDeviceData $device) use ($macAddress, $bridge, $hasDesiredVlanTag, $vlanTag) { + $needsFirewall = $device->isFirewallEnabled !== true; + $needsMac = $macAddress !== null && $macAddress !== $device->macAddress; + $needsBridge = $bridge !== null && $bridge !== $device->bridge; + $needsVlanTag = $hasDesiredVlanTag && $vlanTag !== $device->vlanTag; + + return $needsFirewall || $needsMac || $needsBridge || $needsVlanTag; + }); + + // Nothing to change — skip the write entirely rather than POST an + // empty (digest-only) config update. + if ($devicesToUpdate->isEmpty()) { + return; + } + + $networkDevices = $devicesToUpdate + ->map(function (NetworkDeviceData $device) use ($macAddress, $bridge, $hasDesiredVlanTag, $vlanTag) { + $device->isFirewallEnabled = true; + $device->macAddress = $macAddress ?? $device->macAddress; + $device->bridge = $bridge ?? $device->bridge; + if ($hasDesiredVlanTag) { + $device->vlanTag = $vlanTag; + } + + return $device->toProxmoxString(); + }) + ->reduce(function (array $carry, array $item) { + [$id, $config] = $item; + $carry[$id] = $config; + + return $carry; + }, []); + + $this->configClient->update($networkDevices, $config->digest); + } + + /** + * @throws RequestException + */ + private function syncCloudinitIpConfig(Server $server): void + { + $primaryAddresses = $this->getPrimaryAddresses($server); + + $this->cloudinitService->setIpConfig($server, $primaryAddresses->ipv4, $primaryAddresses->ipv6); + } + + /** + * @throws RequestException + */ + private function lockServerAddresses(Server $server): void + { + $addresses = array_unique($server->addresses()->pluck('ip')->all()); + + $this->configClient + ->setServer($server) + ->getConfig() + ->networkDevices + ->each( + /** + * @throws RequestException + */ + function (NetworkDeviceData $device) use ($server, $addresses) { + [$deviceId, $_] = $device->toProxmoxString(); + $this->firewallService->lockIps( + $server, + $addresses, + "ipfilter-$deviceId", + ); + }); + } + + public function getPrimaryAddresses(Server $server): PrimaryAddressesData + { + return new PrimaryAddressesData( + ipv4: $server->primaryIPv4Address ?? $server->addresses() + ->whereHas('addressBlock', fn ($query) => $query->where('version', 'ipv4')) + ->first(), + ipv6: $server->primaryIPv6Address ?? $server->addresses() + ->whereHas('addressBlock', fn ($query) => $query->where('version', 'ipv6')) + ->first(), + ); + } + + /** + * Allocates the addresses to the server. Changes do not fully activate without running syncSettings(). + * Also, you better fucking make sure that the addresses are accessible to the server's node. + * + * @param int[]|Address[] $addresses + */ + public function syncAddresses(Server $server, array $addresses): void + { + // Normalize input: get array of address IDs + $addressIds = collect($addresses)->map(function ($address) { + return $address instanceof Address ? $address->id : $address; + })->unique()->values()->all(); + + // Get current address IDs attached to this server + $currentAddresses = $server->addresses()->pluck('id')->toArray(); + + // Determine which addresses to add and remove + $addressesToAdd = array_diff($addressIds, $currentAddresses); + $addressesToRemove = array_diff($currentAddresses, $addressIds); + + // Attach new addresses. The `state = available` guard means a reserved address is never + // silently assigned (reserved is fully locked), and it flips available -> assigned. + if (! empty($addressesToAdd)) { + Address::query() + ->where('state', AddressState::Available) + ->whereIn('id', $addressesToAdd) + ->update(['server_id' => $server->id, 'state' => AddressState::Assigned, 'state_reason' => null]); + } + + // Detach addresses no longer associated (assigned -> available). + if (! empty($addressesToRemove)) { + Address::query() + ->where('server_id', $server->id) + ->whereIn('id', $addressesToRemove) + ->update(['server_id' => null, 'state' => AddressState::Available, 'state_reason' => null]); + } + } +} diff --git a/app/Services/Servers/ServerResourceService.php b/app/Services/Servers/ServerResourceService.php new file mode 100644 index 00000000000..fa7154ecb5f --- /dev/null +++ b/app/Services/Servers/ServerResourceService.php @@ -0,0 +1,33 @@ +uuid}.storage_usage"; + + return Cache::remember(key: $cacheKey, ttl: 60, callback: function () use ($server): array { + $fsInfo = $this->client->setServer($server)->getFsInfo(); + + // Calculate total used bytes from all filesystems + // We sum up all valid filesystems. + $used = $fsInfo->sum('usedBytes'); + $total = $fsInfo->sum('totalBytes'); + + return [ + 'used_bytes' => $used, + 'total_bytes' => $total, + ]; + }); + } +} diff --git a/app/Services/Servers/ServerSuspensionService.php b/app/Services/Servers/ServerSuspensionService.php index ab79ee60bfc..37f9e01a7eb 100644 --- a/app/Services/Servers/ServerSuspensionService.php +++ b/app/Services/Servers/ServerSuspensionService.php @@ -1,41 +1,48 @@ isSuspended()) { return; } + $previous = $server->suspended_at; + $server->update([ - 'status' => $isSuspending ? Status::SUSPENDED->value : null, + 'suspended_at' => $isSuspending ? now() : null, ]); try { - $this->powerRepository->setServer($server)->send($isSuspending ? PowerAction::KILL : PowerAction::START); + $this->powerClient->setServer($server)->send($isSuspending ? PowerCommand::KILL : PowerCommand::START); } catch (Exception $exception) { - $server->update([ - 'status' => $isSuspending ? null : Status::SUSPENDED->value, - ]); + // Restore the timestamp we replaced rather than recomputing it: on a failed + // unsuspend that puts the original suspension time back, instead of silently + // resetting the clock to now. + $server->update(['suspended_at' => $previous]); throw $exception; } diff --git a/app/Services/Servers/SyncBuildService.php b/app/Services/Servers/SyncBuildService.php deleted file mode 100644 index 4503fc317aa..00000000000 --- a/app/Services/Servers/SyncBuildService.php +++ /dev/null @@ -1,63 +0,0 @@ -allocationRepository->setServer($server); - - $eloquentDetails = $this->detailService->getByEloquent($server); - $disks = $this->allocationService->getDisks($server); - $bootOrder = $this->allocationService->getBootOrder($server); - - $this->allocationService->syncSettings($server); - - /* Sync metadata */ - $this->cloudinitService->updateHostname($server, $eloquentDetails->hostname); - - /* Sync network configuration */ - $this->networkService->syncSettings($server); - - // find a disk that has a corresponding disk in the deployment - $disksArray = collect($disks->toArray())->pluck('interface')->all(); - $bootOrder = array_filter( - collect($bootOrder->filter(fn (DiskData $disk) => !$disk->is_media)->toArray())->pluck( - 'interface', - )->toArray(), fn ($disk) => in_array($disk, $disksArray), - ); - - if (count($bootOrder) > 0) { - /** @var DiskData $disk */ - $disk = $disks->where('interface', '=', DiskInterface::from(Arr::first($bootOrder))) - ->first(); - - $diff = $server->disk - $disk->size; - - if ($diff > 0) { - $this->diskRepository->setServer($server)->resizeDisk( - $disk->interface, $server->disk, - ); - } - } - } -} diff --git a/app/Services/Servers/VmSyncService.php b/app/Services/Servers/VmSyncService.php new file mode 100644 index 00000000000..6a1fea02da4 --- /dev/null +++ b/app/Services/Servers/VmSyncService.php @@ -0,0 +1,80 @@ + null; + } + + $this->stampIdentity($server); + + $this->allocationService->syncSettings($server); + $onProgress(); + + // Materialize any secondary data disks (each on its own storage) after + // the primary/clone is in place. + $this->allocationService->syncDisks($server); + + $this->cloudinitService->setHostname($server, $server->hostname); + $onProgress(); + + $this->networkService->syncSettings($server); + $onProgress(); + } + + /** + * Writes the server's identity into the guest's `smbios1` config, where it + * travels with the config file through migrations and HA recovery and lets + * the placement reconciler confirm "same guest, new node" before touching + * `node_id` (see ServerPlacementService). + * + * Runs on every build and rebuild: a rebuild is a fresh clone carrying a + * freshly generated PVE uuid, so the stored value is re-asserted each time + * rather than only minted once. Only the uuid field is replaced -- a + * template may carry other smbios1 fields (manufacturer branding and the + * like) that are its own business. + * + * @throws RequestException + * @throws ConnectionException + */ + private function stampIdentity(Server $server): void + { + $uuid = $server->smbios_uuid ?? Str::lower(Str::uuid()->toString()); + + $config = $this->configClient->setServer($server)->getRawConfig(); + + $fields = array_values(array_filter( + explode(',', $config['smbios1'] ?? ''), + fn (string $field) => $field !== '' && ! Str::startsWith($field, 'uuid='), + )); + + array_unshift($fields, "uuid={$uuid}"); + + $this->configClient->update(['smbios1' => implode(',', $fields)]); + + if ($server->smbios_uuid !== $uuid) { + $server->forceFill(['smbios_uuid' => $uuid])->save(); + } + } +} diff --git a/app/Services/Users/AccountPolicyResolver.php b/app/Services/Users/AccountPolicyResolver.php new file mode 100644 index 00000000000..011d2be0283 --- /dev/null +++ b/app/Services/Users/AccountPolicyResolver.php @@ -0,0 +1,50 @@ +root_admin) { + return AccountCapabilitiesData::unrestricted(); + } + + return $this->global(); + } + + /** + * The panel-wide policy, before the admin exemption. This is the tier the + * admin Settings screen edits. + */ + public function global(): AccountCapabilitiesData + { + return new AccountCapabilitiesData( + canChangeName: $this->settings->allow_name_change, + canChangeEmail: $this->settings->allow_email_change, + canChangePassword: $this->settings->allow_password_change, + canChangeAvatar: $this->settings->allow_avatar_change, + ); + } +} diff --git a/app/Services/Users/AvatarService.php b/app/Services/Users/AvatarService.php new file mode 100644 index 00000000000..acdf6cb9a6a --- /dev/null +++ b/app/Services/Users/AvatarService.php @@ -0,0 +1,253 @@ +decode($upload); + + try { + $canvas = $this->square($source, $crop); + + try { + $bytes = $this->encode($canvas); + } finally { + imagedestroy($canvas); + } + } finally { + imagedestroy($source); + } + + // Namespaced by the account and named after the bytes: replacing an + // avatar writes a new file rather than overwriting a cached one, so the + // URL changes with the picture and can be cached forever. + $path = "avatars/{$user->uuid}/".hash('sha256', $bytes).'.webp'; + + $disk = Filesystem::disk($this->diskName()); + $disk->put($path, $bytes); + + $previous = $user->avatar_path; + + $user->forceFill(['avatar_path' => $path])->save(); + + if ($previous && $previous !== $path) { + $disk->delete($previous); + } + + return $user; + } + + public function remove(User $user): User + { + $previous = $user->avatar_path; + + $user->forceFill(['avatar_path' => null])->save(); + + if ($previous) { + Filesystem::disk($this->diskName())->delete($previous); + } + + return $user; + } + + /** + * Everything the account owns on the avatars disk. + * + * Deleting the account deletes the directory, not just the file the column + * points at, so a write that raced a deletion cannot leave a picture behind. + */ + public function purge(User $user): void + { + Filesystem::disk($this->diskName())->deleteDirectory("avatars/{$user->uuid}"); + } + + public function diskName(): string + { + return (string) config('convoy.avatars.disk', 'local'); + } + + /** + * The upload as a GD image, or a validation error the form can render. + * + * `getimagesize` reads the header rather than trusting the filename or the + * browser-supplied content type, so this is also the check that the file is + * the kind of image it claims to be. + */ + private function decode(UploadedFile $upload): GdImage + { + $path = $upload->getRealPath(); + $info = $path ? @getimagesize($path) : false; + + if ($info === false) { + throw ValidationException::withMessages([ + 'avatar' => 'That file is not an image the panel can read.', + ]); + } + + [$width, $height, $type] = $info; + + if ($width * $height > self::MAX_SOURCE_PIXELS) { + throw ValidationException::withMessages([ + 'avatar' => 'That image is too large to process. Use one under 50 megapixels.', + ]); + } + + $image = match ($type) { + IMAGETYPE_JPEG => @imagecreatefromjpeg($path), + IMAGETYPE_PNG => @imagecreatefrompng($path), + IMAGETYPE_WEBP => @imagecreatefromwebp($path), + IMAGETYPE_GIF => @imagecreatefromgif($path), + default => false, + }; + + if (! $image instanceof GdImage) { + throw ValidationException::withMessages([ + 'avatar' => 'That image format is not supported. Use a JPEG, PNG, WebP or GIF.', + ]); + } + + return $type === IMAGETYPE_JPEG + ? $this->orient($image, $path) + : $image; + } + + /** + * Applies the EXIF orientation a phone camera writes instead of rotating the + * pixels. Without this a portrait photo is stored on its side, because the + * tag is metadata GD drops and the browser only honours it on the original. + */ + private function orient(GdImage $image, string $path): GdImage + { + if (! function_exists('exif_read_data')) { + return $image; + } + + $orientation = @exif_read_data($path)['Orientation'] ?? null; + + $rotated = match ($orientation) { + 3 => imagerotate($image, 180, 0), + 6 => imagerotate($image, -90, 0), + 8 => imagerotate($image, 90, 0), + default => null, + }; + + if (! $rotated instanceof GdImage) { + return $image; + } + + imagedestroy($image); + + return $rotated; + } + + /** + * The centred square of the source, scaled to at most {@see self::SIZE}. + * + * Cropping rather than letterboxing because every avatar in the panel is + * rendered in a circle -- padding a wide photo would only put bars inside + * the circle. Small pictures are left at their own size rather than blown + * up to the full 512, which only invents blur. + */ + private function square(GdImage $source, ?AvatarCropData $crop = null): GdImage + { + $width = imagesx($source); + $height = imagesy($source); + + $centred = min($width, $height); + + [$left, $top, $edge] = $crop + ? $this->clamp($crop, $width, $height) + : [ + intdiv($width - $centred, 2), + intdiv($height - $centred, 2), + $centred, + ]; + + $size = min($edge, self::SIZE); + + $canvas = imagecreatetruecolor($size, $size); + + // WebP keeps alpha, and a PNG with a transparent background is a common + // avatar. Without these two calls GD composites it onto black. + imagealphablending($canvas, false); + imagesavealpha($canvas, true); + imagefill($canvas, 0, 0, imagecolorallocatealpha($canvas, 0, 0, 0, 127)); + + imagecopyresampled( + $canvas, + $source, + 0, + 0, + $left, + $top, + $size, + $size, + $edge, + $edge, + ); + + return $canvas; + } + + /** + * The requested crop, pulled back inside the picture. + * + * The browser measures against an image it scaled and the panel against the + * decoded original, so a rounding disagreement of a pixel or two at the + * edge is normal and is not worth a validation error -- but an out-of-bounds + * rectangle makes `imagecopyresampled` read past the bitmap, so it cannot + * be passed through either. + * + * @return array{int, int, int} + */ + private function clamp(AvatarCropData $crop, int $width, int $height): array + { + $edge = max(1, min($crop->size, $width, $height)); + $left = max(0, min($crop->x, $width - $edge)); + $top = max(0, min($crop->y, $height - $edge)); + + return [$left, $top, $edge]; + } + + private function encode(GdImage $image): string + { + ob_start(); + imagewebp($image, null, self::QUALITY); + + return (string) ob_get_clean(); + } +} diff --git a/app/Services/Users/UserDeletionService.php b/app/Services/Users/UserDeletionService.php new file mode 100644 index 00000000000..5fddd1968ae --- /dev/null +++ b/app/Services/Users/UserDeletionService.php @@ -0,0 +1,22 @@ +sessionRevocation->revokeAllForUser($user); + $user->tokens()->delete(); + $this->avatars->purge($user); + $user->delete(); + } +} diff --git a/app/Services/Users/UserInviteService.php b/app/Services/Users/UserInviteService.php new file mode 100644 index 00000000000..fd67ebf39d1 --- /dev/null +++ b/app/Services/Users/UserInviteService.php @@ -0,0 +1,100 @@ +updateOrCreate( + ['user_id' => $user->id], + [ + 'token' => self::hash($token), + 'expires_at' => CarbonImmutable::now()->addDays(config('invites.ttl_days')), + ], + ); + + return $token; + } + + /** + * The invite a token addresses, or null when it is unknown, spent or lapsed. + * + * All three answer identically on purpose: distinguishing them would confirm to whoever is + * holding a guessed token that it once meant something. + */ + public function resolve(string $token): ?UserInvite + { + return UserInvite::query() + ->unexpired() + ->with('user') + ->where('token', '=', self::hash($token)) + ->first(); + } + + /** + * Set the account's password and burn the invite. + * + * Deleting rather than marking consumed: a spent invite carries no information worth + * keeping — the audit log records that it was accepted — and a row that cannot be redeemed + * is one more thing to reason about on every lookup. + */ + public function accept(UserInvite $invite, string $password): User + { + $user = $invite->user; + + $user->update(['password' => $password]); + + $invite->delete(); + + return $user; + } + + public function revoke(User $user): void + { + UserInvite::query()->where('user_id', '=', $user->id)->delete(); + } + + /** + * The link an invite is handed over as. + * + * Built against APP_URL rather than the current request so a link minted by an API call + * from a billing extension points at the panel rather than at whatever host that call + * arrived on. + */ + public static function url(string $token): string + { + return rtrim((string) config('app.url'), '/').'/auth/invite/'.$token; + } + + /** + * Unsalted sha256, matching how Sanctum stores personal access tokens: the input is 48 + * random characters, so there is no dictionary for a salt to defend against, and the lookup + * has to be a single indexed equality check. + */ + private static function hash(string $token): string + { + return hash('sha256', $token); + } +} diff --git a/app/Settings/AccountSettings.php b/app/Settings/AccountSettings.php new file mode 100644 index 00000000000..cf3c2393186 --- /dev/null +++ b/app/Settings/AccountSettings.php @@ -0,0 +1,46 @@ + these defaults -> config('app.url') + * + * It exists because the common case is one panel address that every Anchor + * needs and APP_URL cannot supply (a private tunnel, a split DNS horizon), + * which per-Anchor overrides would force you to repeat on every record. The + * per-Anchor field remains for fleets whose Anchors genuinely reach the panel + * at different addresses. + */ +class AnchorSettings extends Settings +{ + /** + * Where Anchors should reach the panel, or an empty string to use APP_URL. + * + * Stored as a string rather than a nullable one so the shape never changes; + * {@see resolvedPanelUrl()} treats empty as "not set". + */ + public string $panel_url = ''; + + /** + * The panel address an installation with no override of its own is told to + * call. The bottom two tiers of the cascade, resolved. + */ + public function resolvedPanelUrl(): string + { + return rtrim($this->panel_url ?: config('app.url'), '/'); + } + + public static function group(): string + { + return 'anchor'; + } +} diff --git a/app/Settings/AuditSettings.php b/app/Settings/AuditSettings.php new file mode 100644 index 00000000000..a57ea65f0e4 --- /dev/null +++ b/app/Settings/AuditSettings.php @@ -0,0 +1,30 @@ + node override -> these defaults); + * see docs/bandwidth-rate-limiting-plan.md §5. + * + * The action is stored as a plain string ('throttle' | 'disconnect') rather than + * a backed enum so the stored shape never changes; the resolver is responsible + * for turning it into the typed penalty object. + */ +class BandwidthSettings extends Settings +{ + /** + * What happens to a server that exceeds its monthly bandwidth quota, unless + * a node- or server-level override says otherwise. + * + * - 'throttle' -> cap every NIC at {@see $overage_rate} + * - 'disconnect' -> set link_down on every NIC (reversible; the guest keeps + * the NIC but loses carrier) + */ + public string $overage_action = 'throttle'; + + /** + * Throttle target in bytes/s, applied when $overage_action is 'throttle'. + * Defaults to 1 MB/s (Proxmox's floor is 1 MB/s; see the plan §7.1). + */ + public int $overage_rate = 1_000_000; + + public static function group(): string + { + return 'bandwidth'; + } +} diff --git a/app/Settings/MailSettings.php b/app/Settings/MailSettings.php new file mode 100644 index 00000000000..1f0568bfa1e --- /dev/null +++ b/app/Settings/MailSettings.php @@ -0,0 +1,80 @@ +host !== ''; + } + + /** + * @return array + */ + public static function encrypted(): array + { + return ['password']; + } + + public static function group(): string + { + return 'mail'; + } +} diff --git a/app/Support/Anchor/AnchorProtocol.php b/app/Support/Anchor/AnchorProtocol.php new file mode 100644 index 00000000000..5f5c8af5085 --- /dev/null +++ b/app/Support/Anchor/AnchorProtocol.php @@ -0,0 +1,23 @@ + + */ + public const RESOURCES = []; + + public const ACTIONS = ['read', 'write']; + + /** The path prefix stripped before reading the resource segment (e.g. `api/application/`). */ + protected const PATH_PREFIX = ''; + + /** + * Every valid ability string, for validating token creation. Includes `*`, `{resource}:*`, and + * `{resource}:{read|write}`. + * + * @return list + */ + public static function all(): array + { + $abilities = ['*']; + + foreach (static::RESOURCES as $resource) { + $abilities[] = "{$resource}:*"; + foreach (static::ACTIONS as $action) { + $abilities[] = "{$resource}:{$action}"; + } + } + + return $abilities; + } + + /** + * The ability a request requires. Unknown resources require `*`, so a scoped token can never + * reach an endpoint that isn't explicitly in the vocabulary. + */ + public static function requiredFor(Request $request): string + { + $path = Str::of($request->path())->after(static::PATH_PREFIX)->trim('/'); + $resource = $path->before('/')->toString(); + $action = in_array($request->method(), ['GET', 'HEAD'], true) ? 'read' : 'write'; + + if (! in_array($resource, static::RESOURCES, true)) { + return '*'; + } + + return "{$resource}:{$action}"; + } + + /** + * Whether a set of granted abilities satisfies the required one. `*` grants everything, + * `{resource}:*` grants both actions, and `{resource}:write` implies `{resource}:read`. + * + * @param list $granted + */ + public static function grants(array $granted, string $required): bool + { + if (in_array('*', $granted, true) || in_array($required, $granted, true)) { + return true; + } + + if (! str_contains($required, ':')) { + return false; + } + + [$resource, $action] = explode(':', $required, 2); + + if (in_array("{$resource}:*", $granted, true)) { + return true; + } + + // Write access implies read access for the same resource. + return $action === 'read' && in_array("{$resource}:write", $granted, true); + } +} diff --git a/app/Support/Api/TokenAbilities.php b/app/Support/Api/TokenAbilities.php new file mode 100644 index 00000000000..124011f0212 --- /dev/null +++ b/app/Support/Api/TokenAbilities.php @@ -0,0 +1,24 @@ + 1, + self::Kibibytes => 1024, + self::Mebibytes => 1024 ** 2, + self::Gibibytes => 1024 ** 3, + self::Tebibytes => 1024 ** 4, + }; + } + + /** Scale a quantity of this unit up to whole bytes. */ + public function toBytes(int|float $quantity): int + { + return (int) ($quantity * $this->inBytes()); + } + + /** Scale bytes down to this unit (may be fractional). */ + public function fromBytes(int $bytes): int|float + { + return $bytes / $this->inBytes(); + } + + /** + * Parse a Proxmox-style suffixed size ("32G", "4096") into bytes, or null + * when the input isn't a plain integer with an optional K/M/G/T suffix. + */ + public static function parseSize(string $value): ?int + { + if (! preg_match('/^(\d+)([KMGT]?)$/', trim($value), $matches)) { + return null; + } + + return self::from($matches[2])->toBytes((int) $matches[1]); + } + + /** + * Resolve an IEC unit name ("B", "KiB", "MiB", "GiB", "TiB") to its unit, + * or null when unrecognised. Proxmox task logs report progress this way. + */ + public static function fromIec(string $unit): ?self + { + return match (strtoupper(trim($unit))) { + 'B' => self::Bytes, + 'KIB' => self::Kibibytes, + 'MIB' => self::Mebibytes, + 'GIB' => self::Gibibytes, + 'TIB' => self::Tebibytes, + default => null, + }; + } +} diff --git a/app/Support/Jobs/QueuedJobSignatures.php b/app/Support/Jobs/QueuedJobSignatures.php new file mode 100644 index 00000000000..adc81b1c4b2 --- /dev/null +++ b/app/Support/Jobs/QueuedJobSignatures.php @@ -0,0 +1,148 @@ +>> + */ + public static function current(): array + { + $signatures = []; + + foreach (self::classes() as $class) { + $signatures[$class] = self::parametersOf($class); + } + + // Sorted so the snapshot's diff shows what changed rather than how the filesystem + // happened to enumerate the directory that day. + ksort($signatures); + + return $signatures; + } + + /** + * The snapshot as committed. + * + * @return array>> + */ + public static function recorded(): array + { + // Absent only before the first generation; treating that as "nothing recorded" lets the + // refresh command bootstrap the file instead of fataling on it. + return is_file(self::SNAPSHOT) ? require self::SNAPSHOT : []; + } + + /** + * Every concrete queued job class under {@see self::DIRECTORY}. + * + * @return list + */ + private static function classes(): array + { + $classes = []; + + foreach (Finder::create()->files()->in(base_path(self::DIRECTORY))->name('*.php') as $file) { + $class = self::NAMESPACE.str_replace( + ['/', '.php'], + ['\\', ''], + $file->getRelativePathname(), + ); + + if (! class_exists($class)) { + continue; + } + + $reflection = new ReflectionClass($class); + + // Abstract bases and the middleware living alongside the jobs are never serialised + // onto the queue, so their shape is nobody's compatibility problem. + if ($reflection->isAbstract() || ! $reflection->implementsInterface(ShouldQueue::class)) { + continue; + } + + $classes[] = $class; + } + + return $classes; + } + + /** + * @param class-string $class + * @return list> + */ + private static function parametersOf(string $class): array + { + $constructor = (new ReflectionClass($class))->getConstructor(); + + if ($constructor === null) { + return []; + } + + return array_map( + static fn (ReflectionParameter $parameter): array => [ + 'name' => $parameter->getName(), + 'type' => $parameter->hasType() ? (string) $parameter->getType() : 'mixed', + 'optional' => $parameter->isOptional(), + // Recorded because it changes what happens on an old payload: a promoted + // parameter's default does not survive unserialize(), an ordinary property's does. + 'promoted' => $parameter->isPromoted(), + 'variadic' => $parameter->isVariadic(), + ], + $constructor->getParameters(), + ); + } +} diff --git a/app/Support/Jobs/queued-job-signatures.php b/app/Support/Jobs/queued-job-signatures.php new file mode 100644 index 00000000000..d43f7e149ef --- /dev/null +++ b/app/Support/Jobs/queued-job-signatures.php @@ -0,0 +1,84 @@ + [ + ['name' => 'server', 'type' => 'App\\Models\\Server', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Backup\\DeleteBackupJob' => [ + ['name' => 'backup', 'type' => 'App\\Models\\Backup', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Backup\\WaitUntilBackupIsDeletedJob' => [ + ['name' => 'backup', 'type' => 'App\\Models\\Backup', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Node\\MonitorIsoDownloadJob' => [ + ['name' => 'isoId', 'type' => 'int', 'optional' => false, 'promoted' => true, 'variadic' => false], + ['name' => 'upid', 'type' => 'string', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Node\\PollNodeStatusJob' => [ + ['name' => 'nodeId', 'type' => 'int', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Node\\PruneUsersJob' => [ + ['name' => 'nodeId', 'type' => 'int', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Node\\SyncServerUsagesJob' => [ + ['name' => 'nodeId', 'type' => 'int', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\BatchSyncNetworkSettingsJob' => [ + ['name' => 'addressBlock', 'type' => 'App\\Models\\AddressBlock', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\CloneVmJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\ConfigureVmJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\DeleteVmJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\FetchImageJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\ImportVmJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\MonitorBackupJob' => [ + ['name' => 'backup', 'type' => 'App\\Models\\Backup', 'optional' => false, 'promoted' => true, 'variadic' => false], + ['name' => 'upid', 'type' => 'string', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\MonitorBackupRestorationJob' => [ + ['name' => 'server', 'type' => 'App\\Models\\Server', 'optional' => false, 'promoted' => true, 'variadic' => false], + ['name' => 'upid', 'type' => 'string', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\PurgeBackupsJob' => [ + ['name' => 'server', 'type' => 'App\\Models\\Server', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\SendPowerCommandJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ['name' => 'power', 'type' => 'App\\Enums\\Server\\PowerCommand', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\StopVmJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\SyncNetworkSettingsJob' => [ + ['name' => 'server', 'type' => 'App\\Models\\Server', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\SyncServerRateLimitJob' => [ + ['name' => 'server', 'type' => 'App\\Models\\Server', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], + 'App\\Jobs\\Server\\UpdatePasswordJob' => [ + ['name' => 'step', 'type' => 'App\\Models\\DeploymentStep', 'optional' => false, 'promoted' => true, 'variadic' => false], + ['name' => 'password', 'type' => 'string', 'optional' => false, 'promoted' => true, 'variadic' => false], + ], +]; diff --git a/app/Support/Network.php b/app/Support/Network.php new file mode 100644 index 00000000000..b65a0a01849 --- /dev/null +++ b/app/Support/Network.php @@ -0,0 +1,55 @@ + integer conversion). + * + * NOTE: currently unused on `next` — the IPAM overhaul replaced the old + * range-expansion path. Kept here (relocated from the deleted app/Helpers) as + * a reusable utility; safe to drop if it stays unreferenced. + */ +class Network +{ + public static function ipv6ToInteger(string $ip): GMP + { + return gmp_import(inet_pton($ip)); + } + + public static function ipv6FromInteger(GMP $integer): ?string + { + $ip = inet_ntop(str_pad(gmp_export($integer), 16, "\0", STR_PAD_LEFT)); + + return $ip !== false ? $ip : null; + } + + /** + * @return string[] + */ + public static function getAddressesFromRange(AddressVersion $type, string $from, string $to): array + { + /** @var string[] */ + $addresses = []; + + if ($type === AddressVersion::IPv4) { + $from = ip2long($from); + $to = ip2long($to); + + for ($i = $from; $i <= $to; $i++) { + $addresses[] = long2ip($i); + } + } else { + $from = self::ipv6ToInteger($from); + $to = self::ipv6ToInteger($to); + + for ($i = $from; $i <= $to; $i++) { + $addresses[] = self::ipv6FromInteger($i); + } + } + + return $addresses; + } +} diff --git a/app/Support/Passkeys/AuthenticatorAaguids.php b/app/Support/Passkeys/AuthenticatorAaguids.php new file mode 100644 index 00000000000..e84a88e0d60 --- /dev/null +++ b/app/Support/Passkeys/AuthenticatorAaguids.php @@ -0,0 +1,110 @@ +|null */ + private static ?array $names = null; + + /** + * The whole table, keyed by lowercase AAGUID. + * + * @return array + */ + public static function names(): array + { + return self::$names ??= require self::TABLE; + } + + /** + * Drops the memoised copy. Only {@see RefreshAuthenticatorAaguidsCommand} needs this — it + * rewrites the table out from under us, and anything reading it afterwards wants the new one. + */ + public static function forget(): void + { + self::$names = null; + } + + /** + * The recognisable name for an authenticator, or null when we don't know it — either because + * the authenticator is absent from the table or because it reported no AAGUID at all (an + * all-zero AAGUID, which some browsers substitute for privacy). + */ + public static function nameFor(AbstractUid|string|null $aaguid): ?string + { + if ($aaguid === null) { + return null; + } + + $aaguid = mb_strtolower($aaguid instanceof AbstractUid ? $aaguid->toRfc4122() : $aaguid); + + if ($aaguid === '00000000-0000-0000-0000-000000000000') { + return null; + } + + return self::names()[$aaguid] ?? null; + } + + /** + * Turns a raw name from either upstream source into something worth showing a person. + * + * The FIDO Metadata Service describes authenticators for auditors, not end users, so its + * descriptions carry distribution qualifiers that mean nothing here — "(Enterprise Profile)", + * "Preview", the CTAP versions it speaks, internal batch codes. Those come off, and what is + * left is trimmed on a word boundary to {@see Passkey::NAME_MAX_LENGTH} so a name we assign + * automatically is always one a rename would accept back. + * + * Returns an empty string when nothing usable survives; callers should skip those. + */ + public static function displayName(string $raw): string + { + $name = preg_replace( + [ + '/\s*\((?:Enterprise|Consumer)\s+Profile\)/i', + '/\s*\((?:RC\s+)?Preview\)/i', + '/\s*\(CTAP[^)]*\)/i', + '/\s*\b(?:Draft|Preview)\b/', + // A trailing internal batch code, e.g. "YubiKey 5 Series with NFC KVZR57-2". + '/\s+(?=[A-Z0-9-]*[A-Z])(?=[A-Z0-9-]*\d)[A-Z0-9]{5,}(?:-\d+)?$/', + '/\s+/', + ], + ['', '', '', '', '', ' '], + trim($raw), + ); + + $name = trim($name, " -\t\n\r\0\x0B"); + + if (mb_strlen($name) > Passkey::NAME_MAX_LENGTH) { + $name = mb_substr($name, 0, Passkey::NAME_MAX_LENGTH + 1); + $name = mb_substr($name, 0, max(0, (int) mb_strrpos($name, ' '))); + // A cut can leave a dangling connective ("... FIDO 2.1 v1.0 by"). + $name = preg_replace('/\s+(?:by|from|with|for|and|the|of|an?)$/i', '', $name); + } + + return trim($name, " -\t\n\r\0\x0B"); + } +} diff --git a/app/Support/Passkeys/authenticator-names.php b/app/Support/Passkeys/authenticator-names.php new file mode 100644 index 00000000000..4881222096b --- /dev/null +++ b/app/Support/Passkeys/authenticator-names.php @@ -0,0 +1,398 @@ + '1Password', + '50a45b0c-80e7-f944-bf29-f552bfa2e048' => 'ACS FIDO Authenticator', + '973446ca-e21c-9a9b-99f5-9b985a67af0f' => 'ACS FIDO Authenticator Card', + 'c89e6a38-6c00-5426-5aa5-c9cbf48f0382' => 'ACS FIDO Authenticator NFC', + 'cb4f796c-a20a-af9e-d639-213c1ec247f3' => 'ACS PocketKey+ Bio', + 'a11a5faa-9f32-4b8c-8c5d-2f7d13e8c942' => 'AliasVault', + '5ca1ab1e-fa57-1337-f1d0-a117371ca702' => 'Allthenticator Android App: roaming BLE', + '5ca1ab1e-1337-fa57-f1d0-a117e71ca702' => 'Allthenticator iOS App: roaming BLE', + 'b93fd961-f2e6-462f-b122-82002247de78' => 'Android Authenticator', + 'fbfc3007-154e-4ecc-8c0b-6e020557d7bd' => 'Apple Passwords', + '3f59672f-20aa-4afe-b6f4-7e5e916b6d98' => 'Arculus FIDO 2.1 Key Card [P71]', + '9d3df6ba-282f-11ed-a261-0242ac120002' => 'Arculus FIDO2/U2F Key Card', + 'd41f5a69-b817-4144-a13c-9ebd6d9254d6' => 'ATKey.Card CTAP2.0', + 'da1fa263-8b25-42b6-a820-c0036f21ba7f' => 'ATKey.Card NFC', + 'e1a96183-5016-4f24-b55b-e3ae23614cc6' => 'ATKey.Pro CTAP2.0', + 'e416201b-afeb-41ca-a03d-2281c28322aa' => 'ATKey.Pro CTAP2.1', + 'ba76a271-6eb6-4171-874d-b6428dbe3437' => 'ATKey.ProS', + '019614a3-2703-7e35-a453-285fd06c5d24' => 'ATLKey Authenticator', + '1c086528-58d5-f211-823c-356786e36140' => 'Atos CardOS', + 'b267239b-954f-4041-a01b-ee4f33c145b6' => 'authenton1 - CTAP2.1', + 'a4a2d88e-9796-4356-9164-e2a5a8bd019c' => 'Avast Password Manager', + '6bb49926-160a-4306-a100-4eb39ba6ac45' => 'AVG Password Manager', + 'e7db2bd3-f2fe-4d71-ad78-7e7aa166cfd1' => 'Avira Password Manager', + 'd548826e-79b4-db40-a3d8-11116f7e8349' => 'Bitwarden', + 'c9cadfc9-89a9-489e-a25a-c7e86a4d5f15' => 'Burp Suite Navigation Recorder', + '8da0e4dc-164b-454e-972e-88f362b23d59' => 'CardOS FIDO2 Token', + '930b0c03-ef46-4ac4-935c-538dccd1fcdb' => 'Chipwon Clife Key', + 'adce0002-35bc-c60a-648b-0b25f1f05503' => 'Chrome on Mac', + 'b5397666-4885-aa6b-cebf-e52262a439a2' => 'Chromium Browser', + '175cd298-83d2-4a26-b637-313c07a6434e' => 'Chunghwa Telecom FIDO2 Smart Card', + 'fc5ca237-69a0-4f3c-afe4-1ebc66def6df' => 'Clife Key 2', + '23315ad0-6aca-4ba1-952e-f044f1e36976' => 'Clife Key 2 NFC', + 'be727034-574a-f799-5c76-0929e0430973' => 'Crayonic KeyVault K1 (USB-NFC-BLE FIDO2', + '9c835346-796b-4c27-8898-d6032f515cc5' => 'Cryptnox', + '1d1b4e33-76a1-47fb-97a0-14b10d0933f1' => 'Cryptnox FIDO2.1', + '2588ae83-5a3b-4536-b8de-5e540200d191' => 'Dapple Authenticator from Dapple', + '6dae43be-af9c-417b-8b9f-1b611168ec60' => 'Dapple Authenticator from Dapple', + '531126d6-e717-415c-9320-3d9aa6981239' => 'Dashlane', + 'e41b42a3-60ac-4afb-8757-a98f2d7f6c9f' => 'Deepnet SafeKey/Classic (FP)', + 'c1288a5c-d66b-495c-a68f-4e81f9ec5b53' => 'Deepnet SafeKey/Classic (FP) XF', + '357f2718-434f-4124-8a58-7e28c5e4a2fc' => 'Deepnet SafeKey/Classic (NFC)', + 'b12eac35-586c-4809-a4b1-d81af6c305cf' => 'Deepnet SafeKey/Classic (NFC)', + 'b9f6b7b6-f929-4189-bca9-dd951240c132' => 'Deepnet SafeKey/Classic (USB)', + 'de503f9c-21a4-4f76-b4b7-558eb55c6f89' => 'Devolutions', + '771b48fd-d3d4-4f74-9232-fc157ab0507a' => 'Edge on Mac', + '1105e4ed-af1d-02ff-ffff-ffffffffffff' => 'Egomet FIDO2 Authenticator for Android', + 'eb3b131e-59dc-536a-d176-cb7306da10f5' => 'ellipticSecure MIRkey USB Authenticator', + 'f3809540-7f14-49c1-a8b3-8f813b225541' => 'Enpass', + '454e5346-4944-4ffd-6c93-8e9267193e9b' => 'Ensurity AUTH BioPro', + '9eb85bb6-9625-4a72-815d-0487830ccab2' => 'Ensurity AUTH BioPro Desktop', + '50cbf15a-238c-4457-8f16-812c43bf3c49' => 'Ensurity AUTH TouchPro', + '454e5346-4944-4ffd-6c93-8e9267193e9a' => 'Ensurity ThinC', + '24083bcb-3034-4867-99de-a3b52e1d426a' => 'Enterprise Security Key Series with NFC', + 'ab7d1767-3fa0-4388-b6c4-feef7a844809' => 'Enterprise Security Key Series with NFC', + '5343502d-5343-5343-6172-644649444f32' => 'ESS Smart Card Inc. Authenticator', + 'b113a455-cfb6-4c17-8cba-cd952feb7d48' => 'eToken FIDO NFC', + 'a6c5f5d8-2ad0-48b6-8257-e502c8970931' => 'eToken FIDO NFC Enterprise', + 'd716019a-9f4e-4041-9750-17c78f8ae81a' => 'eToken Fusion BIO', + '050dd0bc-ff20-4265-8d5d-305c4b215192' => 'eToken Fusion FIPS', + '10c70715-2a9a-4de1-b0aa-3cff6d496d39' => 'eToken Fusion NFC FIPS', + '146e77ef-11eb-4423-b847-ce77864e9411' => 'eToken Fusion NFC PIV', + 'c3f47802-de73-4dfc-ba22-671fe3304f90' => 'eToken Fusion NFC PIV Enterprise', + '95442b2e-f15e-4def-b270-efb106facb4e' => 'eWBM eFA310 FIDO2 Authenticator', + '87dbc5a1-4c94-4dc8-8a47-97d800fd1f3c' => 'eWBM eFA320 FIDO2 Authenticator', + '361a3082-0278-4583-a16f-72a527f973e4' => 'eWBM eFA500 FIDO2 Authenticator', + '61250591-b2bc-4456-b719-0b17be90bb30' => 'eWBM eFPA FIDO2 Authenticator', + '20f0be98-9af9-986a-4b42-8eca4acb28e4' => 'Excelsecu eSecu FIDO2 Fingerprint', + 'd384db22-4d50-ebde-2eac-5765cf1e2a44' => 'Excelsecu eSecu FIDO2 Fingerprint', + '6002f033-3c07-ce3e-d0f7-0ffe5ed42543' => 'Excelsecu eSecu FIDO2 Fingerprint Key', + 'a3975549-b191-fd67-b8fb-017e2917fdb3' => 'Excelsecu eSecu FIDO2 NFC Security Key', + 'fbefdf68-fe86-0106-213e-4d5fa24cbe2e' => 'Excelsecu eSecu FIDO2 NFC Security Key', + '0d9b2e56-566b-c393-2940-f821b7f15d6d' => 'Excelsecu eSecu FIDO2 Pro Security Key', + 'bbf4b6a7-679d-f6fc-c4f2-8ac0ddf9015a' => 'Excelsecu eSecu FIDO2 PRO Security Key', + 'f573f209-b7fb-b261-671a-d7cf624cc812' => 'Excelsecu eSecu FIDO2 PRO+ Security Key', + 'cdbdaea2-c415-5073-50f7-c04e968640b6' => 'Excelsecu eSecu FIDO2 Security Key', + '12ded745-4bed-47d4-abaa-e713f51d6393' => 'Feitian AllinOne FIDO2 Authenticator', + '77010bd7-212a-4fc9-b236-d2ca5e9d4084' => 'Feitian BioPass FIDO2 Authenticator', + 'a02140b7-0cbd-42e1-a9b5-a39da2545114' => 'Feitian BioPass FIDO2 Plus', + '42df17de-06ba-4177-a2bb-6701be1380d6' => 'Feitian BioPass FIDO2 Plus Authenticator', + 'b6ede29c-3772-412c-8a78-539c1f4c62d2' => 'Feitian BioPass FIDO2 Plus Authenticator', + '2bff89f2-323a-48fc-b7c8-9ff7fe87c07e' => 'Feitian BioPass FIDO2 Pro', + '4c0cf95d-2f40-43b5-ba42-4c83a11c04ba' => 'Feitian BioPass FIDO2 Pro Authenticator', + '12755c32-8ad1-46eb-881c-e0b38d848b09' => 'Feitian ePass FIDO Authenticator', + '39589099-9a75-49fc-afaa-801ca211c62a' => 'Feitian ePass FIDO-NFC', + '78ba3993-d784-4f44-8d6e-cc0a8ad5230e' => 'Feitian ePass FIDO-NFC', + '833b721a-ff5f-4d00-bb2e-bdda3ec01e29' => 'Feitian ePass FIDO2 Authenticator', + 'ee041bce-25e5-4cdb-8f86-897fd6418464' => 'Feitian ePass FIDO2-NFC Authenticator', + '260e3021-482d-442d-838c-7edfbe153b7e' => 'Feitian ePass FIDO2-NFC Plus', + '234cd403-35a2-4cc2-8015-77ea280c77f5' => 'Feitian ePass FIDO2-NFC Series', + '2c0df832-92de-4be1-8412-88a8f074df4a' => 'Feitian FIDO Smart Card', + '238ab2f5-b57f-4917-b3c6-3d3c6c0c350f' => 'FEITIAN FT-JCOS BioCard', + '3e22415d-7fdf-4ea4-8a0c-dd60c4249b9d' => 'Feitian iePass FIDO Authenticator', + 'd2717a32-9851-48a8-9961-b264c97a411a' => 'Fenko Vault', + 'ca87cb70-4c1b-4579-a8e8-4efdd7c007e0' => 'FIDO Alliance TruU Sample FIDO2', + 'f4c63eff-d26c-4248-801c-3736c7eaa93a' => 'FIDO KeyPass S3', + '46544d5d-8f5d-4db4-89ac-ea8977073fff' => 'Foongtone FIDO Authenticator', + '8c97a730-3f7b-41a6-87d6-1e9b62bda6f0' => 'FT-JCOS FIDO Fingerprint Card', + '7a53c643-9dec-4219-b3a4-f9d24aca4e12' => 'G+D StarKey FIDO2-NFC', + 'c09b3399-4a3d-306c-7bdc-967fef47241f' => 'Giesecke+Devrient StarSign FIDO Card 2.1', + '0db01cd6-5618-455b-bb46-1ec203d3213e' => 'GoldKey Security Token', + 'ea9b8d66-4d01-1d21-3ce4-b6b48cb575d4' => 'Google Password Manager', + '42b4fb4a-2866-43b2-9bf7-6c6669c2e5d3' => 'Google Titan Security Key v2', + '6d4aa745-dad5-40c4-b9b4-6a252fcee70f' => 'GoTrust Cyber Key', + '6169eb16-f87a-42d8-978d-e1ac0c3f319f' => 'GoTrust Idem Card', + '9f0d8150-baa5-4c00-9299-ad62c8bb4e87' => 'GoTrust Idem Card', + '3b1adb99-0dfe-46fd-90b8-7f7614a4de2a' => 'GoTrust Idem Key', + 'c611b55c-77b2-4527-8082-590e931b2f08' => 'GoTrust Idem Key', + '72a2b5b1-95a5-4df9-a881-4192aff4f72e' => 'GoTrust Idem Key mini', + '773c30d9-5919-4e96-a4f5-db65e95cf890' => 'GSTAG OAK FIDO2 Authenticator', + 'd49b2120-b865-4191-8cea-be84a52b0485' => 'Heimlane Vault', + 'da583154-ce16-4cdf-9fe6-1dba788c0998' => 'Hey Be Safe', + 'aeb6569c-f8fb-4950-ac60-24ca2bbe2e52' => 'HID Crescendo', + 'c80dbd9a-533f-4a17-b941-1a2f1c7cedff' => 'HID Crescendo', + '0b8b05a4-ebd4-4b0b-8f5f-33d7b6e606ab' => 'HID Crescendo 4000', + '2a55aee6-27cb-42c0-bc6e-04efe999e88a' => 'HID Crescendo 4000', + 'aa79f476-ea00-417e-9628-1e8365123922' => 'HID Crescendo 4000 FIDO', + '8eec9bf9-486c-46da-9a67-1fbb4f66b9ed' => 'HID Crescendo 4000 FIPS', + '54d9fee8-e621-4291-8b18-7157b99c5bec' => 'HID Crescendo Enabled', + 'c4ddaf11-3032-4e77-b3b9-3a340369b9ad' => 'HID Crescendo Fusion', + '692db549-7ae5-44d5-a1e5-dd20a493b723' => 'HID Crescendo Key', + '2d3bec26-15ee-4f5d-88b2-53622490270b' => 'HID Crescendo Key V2', + '7991798a-a7f3-487f-98c0-3faf7a458a04' => 'HID Crescendo Key V3', + '87c13177-85d6-40ac-8c61-fe7ab3de9dfb' => 'HID Crescendo Key V3', + '13ac47cf-1d78-4fd5-9060-aedaabacf826' => 'HID Crescendo Key V3 - Enterprise', + '19bca99b-7c09-44fe-a969-8cba45764542' => 'HID Crescendo Key V3 FIPS', + '3e078ffd-4c54-4586-8baa-a77da113aec5' => 'Hideez Key 3', + '4e768f2c-5fab-48b3-b300-220eb487752b' => 'Hideez Key 4 FIDO2 SDK', + 'd821a7d4-e97c-4cb6-bd82-4237731fd4be' => 'Hyper FIDO Bio Security Key', + '6999180d-630c-442d-b8f7-424b90a43fae' => 'Hyper FIDO Pro', + '9f77e279-a6e2-4d58-b700-31e5943c6a98' => 'Hyper FIDO Pro', + '23195a52-62d9-40fa-8ee5-23b173f4fb52' => 'Hyper FIDO Pro NFC', + '0076631b-d4a0-427f-5773-0ec71c9e0279' => 'HYPR FIDO2 Authenticator', + 'dd4ec289-e01d-41c9-bb89-70fa845d4bf2' => 'iCloud Keychain (Managed)', + 'bb405265-40cf-4115-93e5-a332c1968d8c' => 'ID-One Card', + '82b0a720-127a-4788-b56d-d1d4b2d82eac' => 'ID-One Key', + 'f2145e86-211e-4931-b874-e22bba7d01cc' => 'ID-One Key', + 'e86addcd-7711-47e5-b42a-c18257b0bf61' => 'IDCore 3121 Fido', + '5e264d9d-28ef-4d34-95b4-5941e7a4faa8' => 'Ideem ZSM FIDO2 Authenticator', + '8d1b1fcb-3c76-49a9-9129-5515b346aa02' => 'IDEMIA ID-ONE Card', + '3fd410dc-8ab7-4b86-a1cb-c7174620b2dc' => 'IDEMIA SOLVO Fly 80 R1 FIDO Card', + 'dda9aa35-aaf1-4d3c-b6db-7902fd7dbbbf' => 'IDEMIA SOLVO Fly 80 R3 FIDO Card c', + 'def8ab1a-9f91-44f1-a103-088d8dc7d681' => 'IDEMIA SOLVO Fly 80 R3 FIDO Card e', + 'b68c4b8d-65cb-42ae-b4f6-8606dfba3c22' => 'IDEMIA SOLVO Fly 80 R3 FIDO Card for j', + '49a15c1c-3f63-3f51-23a7-b9e00096edd1' => 'IDEX CTAP2.1 Biometrics', + '39a5647e-1853-446c-a1f6-a79bae9f5bc7' => 'IDmelon', + '820d89ed-d65a-409e-85cb-f73f0578f82a' => 'IDmelon Authenticator', + 'ca4cff1b-5a81-4404-8194-59aabcf1660b' => 'IDPrime 3930 FIDO', + 'b50d5e0a-7f81-4959-9b12-f45407407503' => 'IDPrime 3940 FIDO', + '2194b428-9397-4046-8f39-007a1605a482' => 'IDPrime 931 Fido', + '2ffd6452-01da-471f-821b-ea4bf6c8676a' => 'IDPrime 941 Fido', + '4b89f401-464e-4745-a520-486ddfc5d80e' => 'IIST FIDO2 Authenticator', + '686de81e-fff2-41c1-bb83-2723aaf3e913' => 'IIST SASE USB KEY 1', + '4c50ff10-1057-4fc6-b8ed-43a529530c3c' => 'ImproveID Authenticator', + 'bfc748bb-3429-4faa-b9f9-7cfa9f3b76d0' => 'iPasswords', + 'a10c6dd9-465e-4226-8198-c7c44b91c555' => 'Kaspersky Password Manager', + 'eaecdef2-1c31-5634-8639-f1cbd9c00a08' => 'KeePassDX', + '9addb28c-b46f-4402-808f-019651441ff3' => 'KeePassPasskey', + 'fdb141b2-5d84-443e-8a35-4698c205a502' => 'KeePassXC', + '0ea242b4-43c4-4a1b-8b17-dd6d0b6baec6' => 'Keeper', + 'd91c5288-0ef0-49b7-b8ae-21ca0aa6b3f3' => 'KEY-ID FIDO2 Authenticator', + 'd61d3b87-3e7c-4aea-9c50-441c371903ad' => 'KeyVault Secp256R1 FIDO2 CTAP2', + '4b3f8944-d4f2-4d21-bb19-764a986ec160' => 'KeyXentic FIDO2 Secp256R1 FIDO2 CTAP2', + 'ec31b4cc-2acc-4b8e-9c01-bade00ccbe26' => 'KeyXentic FIDO2 Secp256R1 FIDO2 CTAP2', + 'f7c558a0-f465-11e8-b568-0800200c9a66' => 'KONAI Secp256R1 FIDO2 Conformance', + '560a780c-b6ae-4f03-b110-082f856425b4' => 'KQC QuKey Bio FIDO2 Authenticator', + 'fec067a1-f1d0-4c5e-b4c0-cc3237475461' => 'KX701 SmartToken FIDO', + 'b78a0a55-6ef8-d246-a042-ba0f6d55050c' => 'LastPass', + '1d8cac46-47a1-3386-af50-e88ae46fe802' => 'Ledger Flex FIDO2 Authenticator', + 'b3315166-f36c-b05f-fea8-66a3dfdad171' => 'Ledger Nano Gen5 FIDO2 Authenticator', + '341e4da9-3c2e-8103-5a9f-aad887135200' => 'Ledger Nano S FIDO2 Authenticator', + '58b44d0b-0a7c-f33a-fd48-f7153c871352' => 'Ledger Nano S Plus FIDO2 Authenticator', + 'fcb1bcb4-f370-078c-6993-bc24d0ae3fbe' => 'Ledger Nano X FIDO2 Authenticator', + '6e24d385-004a-16a0-7bfe-efd963845b34' => 'Ledger Stax FIDO2 Authenticator', + '22248c4c-7a12-46e2-9a41-44291b373a4d' => 'LogMeOnce', + '489ff376-b48d-6640-bb69-782a860ca795' => 'Mettlesemi Vishwaas Eagle Authenticator', + 'bb66c294-de08-47e4-b7aa-d12c2cd3fb20' => 'Mettlesemi Vishwaas Hawk Authenticator', + 'd3452668-01fd-4c12-926c-83a4204853aa' => 'Microsoft Password Manager', + 'a7fc3f84-86a3-4da4-a3d7-eb6485a066d8' => 'NEOWAVE Badgeo', + 'c5703116-972b-4851-a3e7-ae1259843399' => 'NEOWAVE Badgeo', + '3789da91-f943-46bc-95c3-50ea2012f03a' => 'NEOWAVE Winkeo', + '2c2aeed8-8174-4159-814b-486e92a261d0' => 'NEOWAVE WINKEO V2.0', + '2cd2f727-f6ca-44da-8f48-5c2e5da000a2' => 'Nitrokey 3 AM', + 'b84e4048-15dc-4dd0-8640-f4f60813c8af' => 'NordPass', + 'fa37f553-f9b6-4adb-ac53-8bbb57ebdf0d' => 'Norton Password Manager', + '07a9f89c-6407-4594-9d56-621d5f1e358b' => 'NXP Semiconductros FIDO2 Conformance', + '0acf3011-bc60-f375-fb53-6f05f43154e0' => 'Nymi FIDO2 Authenticator', + 'a1f52be5-dfab-4364-b51c-2bd496b14a56' => 'OCTATCO EzFinger2 FIDO2 AUTHENTICATOR', + 'bc2fe499-0d8e-4ffe-96f3-94a82840cf8c' => 'OCTATCO EzQuant FIDO2 AUTHENTICATOR', + '69e7c36f-f2f6-9e0d-07a6-bcc243262e6b' => 'OneKey FIDO2 Authenticator', + '70e7c36f-f2f6-9e0d-07a6-bcc243262e6b' => 'OneKey FIDO2 Bluetooth Authenticator', + '30b5035e-d297-4ff1-b00b-addc96ba6a98' => 'OneSpan DIGIPASS FX1 BIO', + '30b5035e-d297-4ff1-020b-addc96ba6a98' => 'OneSpan DIGIPASS FX1-C', + '30b5035e-d297-4ff1-010b-addc96ba6a98' => 'OneSpan DIGIPASS FX1a', + '30b5035e-d297-4ff2-010b-addc96ba6a98' => 'OneSpan DIGIPASS FX2-A', + '30b5035e-d297-4ff7-020b-addc96ba6a98' => 'OneSpan DIGIPASS FX7', + '30b5035e-d297-4ff7-b00b-addc96ba6a98' => 'OneSpan DIGIPASS FX7', + '30b5035e-d297-4ff7-010b-addc96ba6a98' => 'OneSpan DIGIPASS FX7-B', + '30b5035e-d297-4ff7-030b-addc96ba6a98' => 'OneSpan DIGIPASS FX7-C', + '30b5035e-d297-4fc1-b00b-addc96ba6a97' => 'OneSpan FIDO Touch', + '998f358b-2dd2-4cbe-a43a-e8107438dfb3' => 'OnlyKey Secp256R1 FIDO2 CTAP2', + '664d9f67-84a2-412a-9ff7-b4f7d8ee6d05' => 'OpenSK authenticator', + '5ca471bb-a56d-46ad-a496-67e70e9ed9fb' => 'Parcel', + '87f5ec51-f721-4feb-9fe4-be18c4971894' => 'PassCard', + '70617373-7761-6c6c-6669-646f32303236' => 'Passwall', + '53e7a7a5-e75f-4d3d-9483-12fc779cdf23' => 'Password Depot', + '09591fc6-9811-48f7-8f57-b9f23df6413f' => 'Pone Biometrics OFFPAD Authenticator', + '69700f79-d1fb-472e-bd9b-a3a3b9a9eda0' => 'Pone Biometrics OFFPAD Authenticator', + '22682ee5-4f0e-4c19-be3e-797d5770ebfe' => 'Precision InnaIT Key FIDO 2 Level 2', + '522a3f91-5f5d-480d-be37-6cecfad5a27b' => 'Precision InnaIT Key FIDO 2 Level 2', + '53334693-4b3f-4198-8857-53772de2ab65' => 'Precision InnaIT Key FIDO 2 Level 2', + '6832d205-75f2-44c7-a864-e868c796d06e' => 'Precision InnaIT Key FIDO 2 Level 2', + '88bbd2f0-342a-42e7-9729-dd158be5407a' => 'Precision InnaIT Key FIDO 2 Level 2', + '50726f74-6f6e-5061-7373-50726f746f6e' => 'Proton Pass', + 'd350af52-0351-4ba2-acd3-dfeeadc3f764' => 'pwSafe', + '65c97700-f5ef-4d5c-8a42-f30e45ac94b7' => 'Royal Vault', + '7e3f3d30-3557-4442-bdae-139312178b39' => 'RSA', + '59f85fe7-faa5-4c92-9f52-697b9d4d5473' => 'RSA Authenticator 4 for Android', + '8681a073-5f50-4d52-bce4-e21658d207b3' => 'RSA Authenticator 4 for iOS', + 'efb96b10-a9ee-4b6c-a4a9-d32125ccd4a4' => 'Safenet eToken FIDO', + '74820b05-a6c9-40f9-8fb0-9f86aca93998' => 'SafeNet eToken Fusion', + '23786452-f02d-4344-87ed-aaf703726881' => 'SafeNet eToken Fusion CC', + '53414d53-554e-4700-0000-000000000000' => 'Samsung Pass', + '3b3faa7b-2c56-4489-bcd3-53b83ee75768' => 'SECORA Connect SLS21 D1 FIDO 2.1 v1.0', + 'dee49ee1-11cb-47b6-bed0-8e995e67a0fb' => 'SECORA Connect SLS21 D1 FIDO 2.1 v1.0', + '18852056-063b-4042-9814-7d0d383081f9' => 'SECORA ID Key S USB by Infineon', + '9a272558-5cfa-4424-be37-65509677b77d' => 'SECORA ID Key S USB by Infineon Consumer', + '55fd881f-40ba-4eaf-8435-42c5fed08b76' => 'SECORA ID V2 by Infineon Consumer', + '8108bdcd-8483-46b3-b3ce-359f8190325e' => 'SECORA ID V2 by Infineon Enterprise', + '3e9db280-256a-4e17-b08e-19d79e9be166' => 'SECORA ID V2 by Infineon Pay Edition', + '005b20e1-f146-4b87-8f3a-36848ff60ea6' => 'SECORA ID V2 by Infineon Pay Edition M', + '4e2ddbc2-2687-4709-8551-cb66c9776bfe' => 'SECORA ID V2 FIDO2.1 L1', + '5df66f62-5b47-43d3-aa1d-a6e31c8dbeb5' => 'Securitag Assembly Group FIDO', + 'b92c3f9a-c014-4056-887f-140a2501163b' => 'Security Key by Yubico', + 'f8a011f3-8c0a-4d15-8006-17111f9edc7d' => 'Security Key by Yubico', + '149a2021-8ef6-4133-96b8-81f8d5b7f1f5' => 'Security Key by Yubico with NFC', + '6d44ba9b-f6ec-2e49-b930-0c8fe920cb73' => 'Security Key by Yubico with NFC', + '760eda36-00aa-4d29-855b-4012a182cdeb' => 'Security Key NFC by Yubico', + 'a4e9fc6d-4cbe-4758-b8ba-37598bb5bbaa' => 'Security Key NFC by Yubico', + 'b7d3f68e-88a6-471e-9ecf-2df26d041ede' => 'Security Key NFC by Yubico', + 'e77e3c64-05e3-428b-8824-0cbeb04b829d' => 'Security Key NFC by Yubico', + '0bb43545-fd2c-4185-87dd-feb0b2916ace' => 'Security Key NFC by Yubico - Enterprise', + '2772ce93-eb4b-4090-8b73-330f48477d73' => 'Security Key NFC by Yubico - Enterprise', + '47ab2fb4-66ac-4184-9ae1-86be814012d5' => 'Security Key NFC by Yubico - Enterprise', + '72c6b72d-8512-4c66-8359-9d3d10d9222f' => 'Security Key NFC by Yubico - Enterprise', + '9ff4cc65-6154-4fff-ba09-9e2af7882ad2' => 'Security Key NFC by Yubico - Enterprise', + 'ed042a3a-4b22-4455-bb69-a267b652ae7e' => 'Security Key NFC by Yubico - Enterprise', + '0f083f18-4105-43a8-ad69-24e812e38141' => 'Security Key Series with NFC', + '89b19028-256b-4025-8872-255358d950e4' => 'Sentry Enterprises CTAP2 Authenticator', + '57235694-51a5-4a4d-a81a-f42185df6502' => 'SHALO AUTH', + 'e8b7f4a2-c3d5-e6f7-890a-b1c2d3e4f567' => 'Sherlocked', + '912435d9-4a88-42f3-972d-1244b0d51420' => 'SI0X FIDO CL WRIST v1.0', + '516d3969-5a57-5651-5958-4e7a49434167' => 'SmartDisplayer BobeePass FIDO2', + '8876631b-d4a0-427f-5773-0ec71c9e0279' => 'Solo Secp256R1 FIDO2 CTAP2 Authenticator', + '8976631b-d4a0-427f-5773-0ec71c9e0279' => 'Solo Tap Secp256R1 FIDO2 CTAP2', + '9876631b-d4a0-427f-5773-0ec71c9e0279' => 'Somu Secp256R1 FIDO2 CTAP2 Authenticator', + '51787637-8ab8-460c-9302-de0b853d4ffb' => 'SpearID FIDO2 Standard', + '9955a1cd-564c-d388-ad68-9878a27be9f1' => 'StarSign Chase FIDO Card', + 'c89674e3-a765-4b07-888a-7c086fbdf04b' => 'StarSign FIDO Card', + 'f8d5c4e9-e539-4c06-8662-ec2a4155a555' => 'StarSign Key Fob', + 'd9be9d39-e6a6-4c28-a581-32b044d986e4' => 'Sticky Password Manager', + '931327dd-c89b-406c-a81e-ed7058ef36c6' => 'Swissbit iShield Key', + '7787a482-13e8-4784-8a06-c7ed49a7aaf4' => 'Swissbit iShield Key 2', + 'e400ef8c-711d-4692-af46-7f2cf7da23ad' => 'Swissbit iShield Key 2 Enterprise', + '817cdab8-0d51-4de1-a821-e25b88519cf3' => 'Swissbit iShield Key 2 FIPS', + '5eaff75a-dd43-451f-af9f-87c9eeae293e' => 'Swissbit iShield Key 2 FIPS Enterprise', + '5d629218-d3a5-11ed-afa1-0242ac120002' => 'Swissbit iShield Key Pro', + '891494da-2c90-4d31-a9cd-4eab0aed1309' => 'Sésame', + '882adaf5-3aa9-4708-8e7d-3957103775b4' => 'T-Shield TrustSec FIDO2 Bio and client', + '0f00cc22-4640-41e7-9585-384ec73ffe9b' => 'Taglio CTAP2.1 BIO', + '092277e5-8437-46b5-b911-ea64b294acb7' => 'Taglio CTAP2.1 CS', + '7d2afadd-bf6b-44a2-a66b-e831fceb8eff' => 'Taglio CTAP2.1 EP', + 'ab32f0c6-2239-afbb-c470-d2ef4e254db6' => 'TEST (DUMMY RECORD)', + '8836336a-f590-0921-301d-46427531eee6' => 'Thales Bio Android SDK', + '66a0ccb3-bd6a-191f-ee06-e375c50b9846' => 'Thales Bio iOS SDK', + '33d6d7d0-279f-4ef3-96b3-2d3282f4bde6' => 'Thales eToken Fusion BIO Enterprise', + '4d41190c-7beb-4a84-8018-adf265a6352d' => 'Thales IDPrime FIDO Bio', + '04a8fcf2-19c1-457b-911e-69219f17583f' => 'Thales PAY GFCX13 authenticator', + 'cd69adb5-3c7a-deb9-3177-6800ea6cb72a' => 'Thales PIN Android SDK', + '17290f1e-c212-34d0-1423-365d729f09d9' => 'Thales PIN iOS SDK', + '1f8e43df-71ff-e11d-bea3-c4ee7003b232' => 'Thetis Pro FIDO2 Key', + 'c62100de-759b-4bf8-b22b-63b3e3a80401' => 'Token Ring 3 FIDO2 Authenticator', + '91ad6b93-264b-4987-8737-3a690cad6917' => 'Token Ring FIDO2 Authenticator', + 'ab32f0c6-2239-afbb-c470-d2ef4e254db7' => 'TOKEN2 FIDO2 Security Key', + 'eabb46cc-e241-80bf-ae9e-96fa6d2975cf' => 'TOKEN2 PIN Plus Security Key Series', + 'cc45f64e-52a2-451b-831a-4edd8022a202' => 'ToothPic Passkey Provider', + 'bb878d7b-cf54-4784-b390-357030497043' => 'TruU FIDO2 Authenticator', + '95e4d58c-056e-4a65-866d-f5a69659e880' => 'TruU Windows Authenticator', + 'ba86dc56-635f-4141-aef6-00227b1b9af6' => 'TruU Windows Authenticator', + '45e3057e-b2f9-48ed-912f-9b901e153b16' => 'Uniqkey', + 'cfcb13a2-244f-4b36-9077-82b79d6a7de7' => 'USB/NFC Passcode Authenticator', + '73402251-f2a8-4f03-873e-3cb6db604b03' => 'uTrust FIDO2 Security Key', + '5626bed4-e756-430b-a7ff-ca78c8b12738' => 'VALMIDO PRO FIDO', + '5ea308b2-7ac7-48b9-ac09-7e2da9015f8c' => 'Veridium Android SDK', + '6e8d1eae-8d40-4c25-bcf8-4633959afc71' => 'Veridium iOS SDK', + '8d4378b0-725d-4432-b3c2-01fcdaf46286' => 'VeridiumID Passkey Android SDK', + '1e906e14-77af-46bc-ae9f-fe6ef18257e4' => 'VeridiumID Passkey iOS SDK', + 'd94a29d9-52dd-4247-9c2d-8b818b610389' => 'VeriMark Guard Fingerprint Key', + '76692dc1-c56a-48d9-8e7d-31b5ced430ac' => 'VeriMark NFC+ USB-A Security Key', + 'ee7fa1e0-9539-432f-bd43-9c2fc6d4f311' => 'VeriMark NFC+ USB-C Security Key', + '09619fbf-d75e-4a62-be1d-fe4d240864ae' => 'VeriMark(TM) Guard 2.1 Fingerprint', + '99ed6c29-4573-4847-816d-78ad8f1c75ef' => 'VeroCard FIDO2 Authenticator', + '5fdb81b8-53f0-4967-a881-f5ec26fe4d18' => 'VinCSS FIDO2 Authenticator', + '9012593f-43e4-4461-a97a-d92777b55d74' => 'VinCSS FIDO2 Fingerprint', + 'd7a423ad-3e19-4492-9200-78137dccc136' => 'VivoKey Apex', + '477b05cd-7f78-4fe7-b629-27247f296138' => 'WALLIX Vault', + '6e34341a-88c7-483d-b777-a425c355be93' => 'WebComm OETHenticator', + '08987058-cadc-4b81-b6e1-30de50dcbe96' => 'Windows Hello', + '6028b017-b1d4-4c02-b4b3-afcdafc96bb2' => 'Windows Hello', + '9ddd1817-af5a-4672-a2b9-3e3dd95000a9' => 'Windows Hello', + 'f56f58b3-d711-4afc-ba7d-6ac05f88cb19' => 'WinMagic FIDO Eazy - Phone', + '31c3f7ff-bf15-4327-83ec-9336abcbcd34' => 'WinMagic FIDO Eazy - Software', + '970c8d9c-19d2-46af-aa32-3f448db49e35' => 'WinMagic FIDO Eazy - TPM', + '504d7149-4e4c-3841-4555-55445a677357' => 'WiSECURE AuthTron USB FIDO2', + '5753362b-4e6b-6345-7b2f-255438404c75' => 'WiSECURE Blentity FIDO2 Authenticator', + '3aa78eb1-ddd8-46a8-a821-8f8ec57a7bd5' => 'YubiKey 5 CCN Series with NFC', + '3ec9c8d3-a5a7-415b-a7b5-f1d606368d3f' => 'YubiKey 5 CCN Series with NFC', + '4fc84f16-2545-4e53-b8fc-7bf4d7282a10' => 'YubiKey 5 CCN Series with NFC', + 'eb7ef748-cbe0-4b40-b8f6-07bd2d592d35' => 'YubiKey 5 CCN Series with NFC', + '57f7de54-c807-4eab-b1c6-1c9be7984e92' => 'YubiKey 5 FIPS Series', + '73bb0cd4-e502-49b8-9c6f-b59445bf720b' => 'YubiKey 5 FIPS Series', + '905b4cb4-ed6f-4da9-92fc-45e0d4e9b5c7' => 'YubiKey 5 FIPS Series', + 'd2fbd093-ee62-488d-9dad-1e36389f8826' => 'YubiKey 5 FIPS Series', + '3a662962-c6d4-4023-bebb-98ae92e78e20' => 'YubiKey 5 FIPS Series with Lightning', + '5b0e46ba-db02-44ac-b979-ca9b84f5e335' => 'YubiKey 5 FIPS Series with Lightning', + '7b96457d-e3cd-432b-9ceb-c9fdd7ef7432' => 'YubiKey 5 FIPS Series with Lightning', + '85203421-48f9-4355-9bc8-8a53846e5083' => 'YubiKey 5 FIPS Series with Lightning', + '9e66c661-e428-452a-a8fb-51f7ed088acf' => 'YubiKey 5 FIPS Series with Lightning', + '62e54e98-c209-4df3-b692-de71bb6a8528' => 'YubiKey 5 FIPS Series with NFC', + '79f3c8ba-9e35-484b-8f47-53a5a0f5c630' => 'YubiKey 5 FIPS Series with NFC', + 'c1f9a0bc-1dd2-404a-b27f-8e29047a43fd' => 'YubiKey 5 FIPS Series with NFC', + 'ce6bf97f-9f69-4ba7-9032-97adc6ca5cf1' => 'YubiKey 5 FIPS Series with NFC', + 'fcc0118f-cd45-435b-8da1-9782b2da0715' => 'YubiKey 5 FIPS Series with NFC', + '0a357157-9b18-4c8a-920e-d156e972b2f8' => 'YubiKey 5 Series', + '19083c3d-8383-4b18-bc03-8f1c9ab2fd1b' => 'YubiKey 5 Series', + '20ac7a17-c814-4833-93fe-539f0d5e3389' => 'YubiKey 5 Series', + '4599062e-6926-4fe7-9566-9e8fb1aedaa0' => 'YubiKey 5 Series', + '524de2de-982f-49b4-a769-2b5e3b73ad79' => 'YubiKey 5 Series', + 'cb69481e-8ff7-4039-93ec-0a2729a154a8' => 'YubiKey 5 Series', + 'ee882879-721c-4913-9775-3dfcce97072a' => 'YubiKey 5 Series', + 'ff4dac45-ede8-4ec2-aced-cf66103f4335' => 'YubiKey 5 Series', + '03012cb7-4fb2-42e7-9e8d-a81f10e2a5e9' => 'YubiKey 5 Series with Lightning', + '24673149-6c86-42e7-98d9-433fb5b73296' => 'YubiKey 5 Series with Lightning', + '3124e301-f14e-4e38-876d-fbeeb090e7bf' => 'YubiKey 5 Series with Lightning', + '3b24bf49-1d45-4484-a917-13175df0867b' => 'YubiKey 5 Series with Lightning', + 'a02167b9-ae71-4ac7-9a07-06432ebb6f1c' => 'YubiKey 5 Series with Lightning', + 'b90e7dc1-316e-4fee-a25a-56a666a670fe' => 'YubiKey 5 Series with Lightning', + 'c3479970-e58a-4f70-836f-853bf42fb063' => 'YubiKey 5 Series with Lightning', + 'c5ef55ff-ad9a-4b9f-b580-adebafe026d0' => 'YubiKey 5 Series with Lightning', + '1ac71f64-468d-4fe0-bef1-0e5f2f551f18' => 'YubiKey 5 Series with NFC', + '2fc0579f-8113-47ea-b116-bb5a8db9202a' => 'YubiKey 5 Series with NFC', + '34f5766d-1536-4a24-9033-0e294e510fb0' => 'YubiKey 5 Series with NFC', + '41e39911-c669-4811-b860-c6ad0b411b96' => 'YubiKey 5 Series with NFC', + '6ab56fad-881f-4a43-acb2-0be065924522' => 'YubiKey 5 Series with NFC', + '7dab85a5-d16d-4eaf-a7ef-4c1385b151c5' => 'YubiKey 5 Series with NFC', + '9eb7eabc-9db5-49a1-b6c3-555a802093f4' => 'YubiKey 5 Series with NFC', + 'a25342c0-3cdc-4414-8e46-f4807fca511c' => 'YubiKey 5 Series with NFC', + 'd7781e5d-e353-46aa-afe2-3ca49f13332a' => 'YubiKey 5 Series with NFC', + 'f4ce5fc0-57d3-46f5-a736-efb7d5bc63b5' => 'YubiKey 5 Series with NFC', + 'fa2b99dc-9e39-4257-8f92-4a30d23c4118' => 'YubiKey 5 Series with NFC', + '662ef48a-95e2-4aaa-a6c1-5b9c40375824' => 'YubiKey 5 Series with NFC - Enhanced PIN', + 'b2c1a50b-dad8-4dc7-ba4d-0ce9597904bc' => 'YubiKey 5 Series with NFC - Enhanced PIN', + '0ebd9f2c-f685-441c-8c3e-a02a234a840a' => 'YubiKey 5 Series with NFC Enhanced PIN', + '9a3f2abd-a73d-439c-9ee7-1b53a857eaa7' => 'YubiKey 5 Series with NFC Enhanced PIN', + '9dd8d593-2213-438a-97f8-d6b813d51c27' => 'YubiKey Bio Fido Edition', + 'add92433-0d69-4026-8166-29b25bce64e9' => 'YubiKey Bio Fido Edition', + '9806a2c8-c0da-478e-b4ca-620005d34182' => 'YubiKey Bio Multi-protocol Edition', + 'ba0a9266-40d8-4048-9786-d710b5474752' => 'YubiKey Bio Multi-protocol Edition', + 'dc5e949d-f939-43b3-9877-a85c7186b753' => 'YubiKey Bio Multi-protocol Edition', + '7409272d-1ff9-4e10-9fc9-ac0019c124fd' => 'YubiKey Bio Series - FIDO Edition', + '83c47309-aabb-4108-8470-8be838b573cb' => 'YubiKey Bio Series - FIDO Edition', + '8c39ee86-7f9a-4a95-9ba3-f6b097e5c2ee' => 'YubiKey Bio Series - FIDO Edition', + 'ad08c78a-4e41-49b9-86a2-ac15b06899e2' => 'YubiKey Bio Series - FIDO Edition', + 'd8522d9f-575b-4866-88a9-ba99fa02f35b' => 'YubiKey Bio Series - FIDO Edition', + 'dd86a2da-86a0-4cbe-b462-4bd31f57bc6f' => 'YubiKey Bio Series - FIDO Edition', + '34744913-4f57-4e6e-a527-e9ec3c4b94e6' => 'YubiKey Bio Series - Multi-protocol', + '58276709-bb4b-4bb3-baf1-60eea99282a7' => 'YubiKey Bio Series - Multi-protocol', + '6ec5cff2-a0f9-4169-945b-f33b563f7b99' => 'YubiKey Bio Series - Multi-protocol', + '7d1351a6-e097-4852-b8bf-c9ac5c9ce4a3' => 'YubiKey Bio Series - Multi-protocol', + '90636e1f-ef82-43bf-bdcf-5255f139d12f' => 'YubiKey Bio Series - Multi-protocol', + '97e6a830-c952-4740-95fc-7c78dc97ce47' => 'YubiKey Bio Series - Multi-protocol', + 'b35a26b2-8f6e-4697-ab1d-d44db4da28c6' => 'Zoho Vault', + '99bf4610-ec26-4252-b31f-7380ccd59db5' => 'ZTPass SmartAuth', + 'b415094c-49d3-4c8b-b3fe-7d0ad28a6bc4' => 'ZTPass SmartAuth', +]; diff --git a/app/Support/StorageBackends.php b/app/Support/StorageBackends.php new file mode 100644 index 00000000000..0faf96dd018 --- /dev/null +++ b/app/Support/StorageBackends.php @@ -0,0 +1,41 @@ + $deployment->update([ + 'status' => DeploymentStatus::RUNNING, + 'started_at' => now(), + ]); + } + + private function onComplete(Deployment $deployment): callable + { + // The deployment's terminal status and the server lifecycle it implies are + // one fact written to two rows. Committing them together keeps the UI's + // two sources of truth from disagreeing if a write is interrupted. + return function () use ($deployment) { + DB::transaction(function () use ($deployment) { + $deployment->update([ + 'status' => DeploymentStatus::COMPLETED, + 'completed_at' => now(), + ]); + $deployment->server->update(['lifecycle' => ServerLifecycle::READY]); + }); + }; + } + + private function onFail(Deployment $deployment, ServerLifecycle $serverStatus = ServerLifecycle::INSTALL_FAILED): callable + { + return function () use ($deployment, $serverStatus) { + DB::transaction(function () use ($deployment, $serverStatus) { + $deployment->update([ + 'status' => DeploymentStatus::FAILED, + 'completed_at' => now(), + ]); + // `lifecycle`, not `status`: there is no `status` column on + // servers, so this threw inside the chain's catch callback and + // the failure was never recorded — the deployment stayed + // running and the server sat in `installing` forever, with the + // install screen up and no way off it but a rebuild. + $deployment->server->update(['lifecycle' => $serverStatus]); + }); + }; + } +} diff --git a/app/Traits/HandlesProxmoxErrors.php b/app/Traits/HandlesProxmoxErrors.php new file mode 100644 index 00000000000..1a206d83f4b --- /dev/null +++ b/app/Traits/HandlesProxmoxErrors.php @@ -0,0 +1,42 @@ +response->json(), 'message', ''), $message)) { + return true; + } + + return false; + } + + /** + * Leave a trace when a nonexistent-VM error is treated as success. Usually + * the VM really is gone and this line is noise -- but "does not exist" is + * also exactly what the *recorded* node answers after PVE moved the guest + * elsewhere (HA recovery, migration), in which case the action silently + * did nothing. The placement reconciler re-homes the row within a poll + * cycle; this line is what connects the two events in the log. + */ + protected function logSwallowedNonexistentVM(Server $server, string $action): void + { + Log::warning('Treated nonexistent-VM error as success; if the guest was migrated off this node, the action did not reach it', [ + 'server' => $server->id, + 'vmid' => $server->vmid, + 'node' => $server->node->name, + 'action' => $action, + ]); + } +} diff --git a/app/Traits/Jobs/FailsWithStep.php b/app/Traits/Jobs/FailsWithStep.php new file mode 100644 index 00000000000..683a8ef3c0a --- /dev/null +++ b/app/Traits/Jobs/FailsWithStep.php @@ -0,0 +1,22 @@ +step->markFailed($exception); + } +} diff --git a/app/Transformers/Admin/AddressPoolTransformer.php b/app/Transformers/Admin/AddressPoolTransformer.php deleted file mode 100644 index 1a6425b9856..00000000000 --- a/app/Transformers/Admin/AddressPoolTransformer.php +++ /dev/null @@ -1,27 +0,0 @@ - $pool->id, - 'name' => $pool->name, - 'nodes_count' => (int) $pool->nodes_count, - 'addresses_count' => (int) $pool->addresses_count, - ]; - } - - public function includeAddresses(AddressPool $pool): Collection - { - return $this->collection($pool->addresses, new AddressTransformer()); - } -} diff --git a/app/Transformers/Admin/AddressTransformer.php b/app/Transformers/Admin/AddressTransformer.php deleted file mode 100644 index 19ffb7fd3ff..00000000000 --- a/app/Transformers/Admin/AddressTransformer.php +++ /dev/null @@ -1,25 +0,0 @@ -toArray())->toArray(); - } - - public function includeServer(Address $address): ?Item - { - return !is_null($address->server) ? $this->item($address->server, new ServerTransformer()) : null; - } -} diff --git a/app/Transformers/Admin/ApiKeyTransformer.php b/app/Transformers/Admin/ApiKeyTransformer.php deleted file mode 100644 index c7577b4f453..00000000000 --- a/app/Transformers/Admin/ApiKeyTransformer.php +++ /dev/null @@ -1,32 +0,0 @@ - $token->id, - 'type' => $token->type, - 'name' => $token->name, - 'last_used_at' => $token->last_used_at, - ]; - } - - public function includeUser(PersonalAccessToken $token) - { - return $this->item($token->tokenable, new UserTransformer); - } -} diff --git a/app/Transformers/Admin/CotermTransformer.php b/app/Transformers/Admin/CotermTransformer.php deleted file mode 100644 index d366994226e..00000000000 --- a/app/Transformers/Admin/CotermTransformer.php +++ /dev/null @@ -1,32 +0,0 @@ - (int)$coterm->id, - 'name' => $coterm->name, - 'is_tls_enabled' => (boolean)$coterm->is_tls_enabled, - 'fqdn' => $coterm->fqdn, - 'port' => (int)$coterm->port, - 'nodes_count' => (int)$coterm->nodes_count, - ]; - - if ($this->includeToken) { - $transformed['token_id'] = $coterm->token_id; - $transformed['token'] = $coterm->token; - } - - return $transformed; - } -} diff --git a/app/Transformers/Admin/FileMetadataTransformer.php b/app/Transformers/Admin/FileMetadataTransformer.php deleted file mode 100644 index d152da58300..00000000000 --- a/app/Transformers/Admin/FileMetadataTransformer.php +++ /dev/null @@ -1,14 +0,0 @@ -toArray(); - } -} diff --git a/app/Transformers/Admin/IsoTransformer.php b/app/Transformers/Admin/IsoTransformer.php deleted file mode 100644 index e8d02843cf7..00000000000 --- a/app/Transformers/Admin/IsoTransformer.php +++ /dev/null @@ -1,23 +0,0 @@ - $iso->uuid, - 'is_successful' => $iso->is_successful, - 'name' => $iso->name, - 'file_name' => $iso->file_name, - 'size' => $iso->size, - 'hidden' => $iso->hidden, - 'completed_at' => $iso->completed_at, - 'created_at' => $iso->created_at, - ]; - } -} diff --git a/app/Transformers/Admin/LocationTransformer.php b/app/Transformers/Admin/LocationTransformer.php deleted file mode 100644 index 6e6c5524c3e..00000000000 --- a/app/Transformers/Admin/LocationTransformer.php +++ /dev/null @@ -1,20 +0,0 @@ - $location->id, - 'short_code' => $location->short_code, - 'description' => $location->description, - 'nodes_count' => (int) $location->nodes_count, - 'servers_count' => (int) $location->servers_count, - ]; - } -} diff --git a/app/Transformers/Admin/NewApiKeyTransformer.php b/app/Transformers/Admin/NewApiKeyTransformer.php deleted file mode 100644 index 5a7cf62a720..00000000000 --- a/app/Transformers/Admin/NewApiKeyTransformer.php +++ /dev/null @@ -1,33 +0,0 @@ - $token->accessToken->id, - 'type' => $token->accessToken->type, - 'name' => $token->accessToken->name, - 'last_used_at' => $token->accessToken->last_used_at, - 'plain_text_token' => $token->plainTextToken, - ]; - } - - public function includeUser(NewAccessToken $token) - { - return $this->item($token->accessToken->tokenable, new UserTransformer); - } -} diff --git a/app/Transformers/Admin/NodeTransformer.php b/app/Transformers/Admin/NodeTransformer.php deleted file mode 100644 index 47449c13105..00000000000 --- a/app/Transformers/Admin/NodeTransformer.php +++ /dev/null @@ -1,34 +0,0 @@ - $node->id, - 'location_id' => $node->location_id, - 'name' => $node->name, - 'cluster' => $node->cluster, - 'verify_tls' => $node->verify_tls, - 'fqdn' => $node->fqdn, - 'port' => $node->port, - 'memory' => $node->memory, - 'memory_overallocate' => $node->memory_overallocate, - 'memory_allocated' => $node->memory_allocated, - 'disk' => $node->disk, - 'disk_overallocate' => $node->disk_overallocate, - 'disk_allocated' => $node->disk_allocated, - 'vm_storage' => $node->vm_storage, - 'backup_storage' => $node->backup_storage, - 'iso_storage' => $node->iso_storage, - 'network' => $node->network, - 'coterm_id' => $node->coterm_id, - 'servers_count' => (int)$node->servers_count, - ]; - } -} diff --git a/app/Transformers/Admin/OverviewTransformer.php b/app/Transformers/Admin/OverviewTransformer.php deleted file mode 100644 index 694b081c02b..00000000000 --- a/app/Transformers/Admin/OverviewTransformer.php +++ /dev/null @@ -1,74 +0,0 @@ - $overview['generated_at'], - 'summary' => [ - 'servers' => $overview['summary']['servers'], - 'nodes' => $overview['summary']['nodes'], - 'users' => $overview['summary']['users'], - 'locations' => $overview['summary']['locations'], - 'failed_servers' => $overview['summary']['failed_servers'], - ], - 'servers' => [ - 'total' => $overview['servers']['total'], - 'ready' => $overview['servers']['ready'], - 'installing' => $overview['servers']['installing'], - 'suspended' => $overview['servers']['suspended'], - 'restoring' => $overview['servers']['restoring'], - 'deleting' => $overview['servers']['deleting'], - 'failed' => $overview['servers']['failed'], - 'statuses' => $overview['servers']['statuses'], - ], - 'capacity' => [ - 'memory' => $this->metric($overview['capacity']['memory']), - 'disk' => $this->metric($overview['capacity']['disk']), - ], - 'addresses' => [ - 'pools' => $overview['addresses']['pools'], - 'total' => $overview['addresses']['total'], - 'assigned' => $overview['addresses']['assigned'], - 'available' => $overview['addresses']['available'], - 'percent' => $overview['addresses']['percent'], - ], - 'backups' => [ - 'total' => $overview['backups']['total'], - 'successful' => $overview['backups']['successful'], - 'pending' => $overview['backups']['pending'], - 'failed' => $overview['backups']['failed'], - ], - 'isos' => [ - 'total' => $overview['isos']['total'], - 'successful' => $overview['isos']['successful'], - 'pending' => $overview['isos']['pending'], - ], - 'nodes' => collect($overview['nodes']) - ->map(fn (array $node) => [ - 'id' => $node['id'], - 'name' => $node['name'], - 'cluster' => $node['cluster'], - 'fqdn' => $node['fqdn'], - 'servers' => $node['servers'], - 'memory' => $this->metric($node['memory']), - 'disk' => $this->metric($node['disk']), - ]) - ->all(), - ]; - } - - private function metric(array $metric): array - { - return [ - 'allocated' => $metric['allocated'], - 'total' => $metric['total'], - 'percent' => $metric['percent'], - ]; - } -} diff --git a/app/Transformers/Admin/ServerBuildTransformer.php b/app/Transformers/Admin/ServerBuildTransformer.php deleted file mode 100644 index cc74ec472db..00000000000 --- a/app/Transformers/Admin/ServerBuildTransformer.php +++ /dev/null @@ -1,42 +0,0 @@ -getByEloquent($server); - - $data = $serverEloquentData->toArray(); - - $data['node_id'] = $server->node_id; - $data['user_id'] = $server->user_id; - $data['vmid'] = $server->vmid; - $data['internal_id'] = $data['id']; - $data['id'] = $data['uuid_short']; - unset($data['uuid_short']); - - return $data; - } - - public function includeUser(Server $server) - { - return $this->item($server->user, new UserTransformer); - } - - public function includeNode(Server $server) - { - return $this->item($server->node, new NodeTransformer); - } -} diff --git a/app/Transformers/Admin/ServerTransformer.php b/app/Transformers/Admin/ServerTransformer.php deleted file mode 100644 index 9379c772e5e..00000000000 --- a/app/Transformers/Admin/ServerTransformer.php +++ /dev/null @@ -1,25 +0,0 @@ - $server->id, - 'uuid' => $server->uuid, - 'uuid_short' => $server->uuid_short, - 'user_id' => $server->user_id, - 'node_id' => $server->node_id, - 'vmid' => $server->vmid, - 'hostname' => $server->hostname, - 'name' => $server->name, - 'description' => $server->description, - 'status' => $server->status, - ]; - } -} diff --git a/app/Transformers/Admin/TemplateGroupTransformer.php b/app/Transformers/Admin/TemplateGroupTransformer.php deleted file mode 100644 index a3a27014360..00000000000 --- a/app/Transformers/Admin/TemplateGroupTransformer.php +++ /dev/null @@ -1,33 +0,0 @@ - $templateGroup->id, - 'node_id' => $templateGroup->node_id, - 'uuid' => $templateGroup->uuid, - 'name' => $templateGroup->name, - 'hidden' => $templateGroup->hidden, - 'order_column' => $templateGroup->order_column, - ]; - } - - public function includeTemplates(TemplateGroup $templateGroup) - { - return $this->collection($templateGroup->templates, new TemplateTransformer); - } -} diff --git a/app/Transformers/Admin/TemplateTransformer.php b/app/Transformers/Admin/TemplateTransformer.php deleted file mode 100644 index b223aed94ec..00000000000 --- a/app/Transformers/Admin/TemplateTransformer.php +++ /dev/null @@ -1,22 +0,0 @@ - $template->id, - 'template_group_id' => $template->template_group_id, - 'uuid' => $template->uuid, - 'name' => $template->name, - 'vmid' => $template->vmid, - 'hidden' => $template->hidden, - 'order_column' => $template->order_column, - ]; - } -} diff --git a/app/Transformers/Admin/UserTransformer.php b/app/Transformers/Admin/UserTransformer.php deleted file mode 100644 index 9abf3520ffb..00000000000 --- a/app/Transformers/Admin/UserTransformer.php +++ /dev/null @@ -1,21 +0,0 @@ - $user->id, - 'name' => $user->name, - 'email' => $user->email, - 'email_verified_at' => $user->email_verified_at, - 'root_admin' => $user->root_admin, - 'servers_count' => (int) $user->servers_count, - ]; - } -} diff --git a/app/Transformers/Application/SSOTokenTransformer.php b/app/Transformers/Application/SSOTokenTransformer.php deleted file mode 100644 index 1430d9c0d2b..00000000000 --- a/app/Transformers/Application/SSOTokenTransformer.php +++ /dev/null @@ -1,17 +0,0 @@ - $token->user_id, - 'token' => $token->token, - ]; - } -} diff --git a/app/Transformers/Client/ActivityLogTransformer.php b/app/Transformers/Client/ActivityLogTransformer.php deleted file mode 100644 index 83fff9b8f54..00000000000 --- a/app/Transformers/Client/ActivityLogTransformer.php +++ /dev/null @@ -1,127 +0,0 @@ -call([$this, 'loadDependencies']); - } - - public function loadDependencies(Request $request) - { - $this->request = $request; - } - - public function transform(ActivityLog $model): array - { - return [ - // This is not for security, it is only to provide a unique identifier to - // the front-end for each entry to improve rendering performance since there - // is nothing else sufficiently unique to key off at this point. - 'id' => $model->id, - 'batch' => $model->batch, - 'event' => $model->event, - 'ip' => $this->canViewIP($model->actor) ? $model->ip : null, - 'description' => $model->description, - 'properties' => $this->properties($model), - 'created_at' => $model->created_at, - 'updated_at' => $model->updated_at, - ]; - } - - public function includeActor(ActivityLog $model) - { - if (! $model->actor instanceof User) { - return $this->null(); - } - - return $this->item($model->actor, new UserTransformer); - } - - /** - * Transforms any array values in the properties into a countable field for easier - * use within the translation outputs. - */ - protected function properties(ActivityLog $model): array - { - if (! $model->properties || $model->properties->isEmpty()) { - return []; - } - - $properties = $model->properties - ->mapWithKeys(function ($value, $key) use ($model) { - if ($key === 'ip' && ! $model->actor?->is($this->request->user())) { - return [$key => '[hidden]']; - } - - if (! is_array($value)) { - // Perform some directory normalization at this point. - if ($key === 'directory') { - $value = str_replace('//', '/', '/'.trim($value, '/').'/'); - } - - return [$key => $value]; - } - - return [$key => $value, "{$key}_count" => count($value)]; - }); - - $keys = $properties->keys()->filter(fn ($key) => Str::endsWith($key, '_count'))->values(); - if ($keys->containsOneItem()) { - $properties = $properties->merge(['count' => $properties->get($keys[0])])->except($keys[0]); - } - - return $properties->toArray(); - } - - /** - * Determines if there are any log properties that we've not already exposed - * in the response language string and that are not just the IP address or - * the browser useragent. - * - * This is used by the front-end to selectively display an "additional metadata" - * button that is pointless if there is nothing the user can't already see from - * the event description. - */ - protected function hasAdditionalMetadata(ActivityLog $model): bool - { - if (is_null($model->properties) || $model->properties->isEmpty()) { - return false; - } - - $str = trans('activity.'.str_replace(':', '.', $model->event)); - preg_match_all('/:(?[\w.-]+\w)(?:[^\w:]?|$)/', $str, $matches); - - $exclude = array_merge($matches['key'], ['ip', 'useragent', 'using_sftp']); - foreach ($model->properties->keys() as $key) { - if (! in_array($key, $exclude, true)) { - return true; - } - } - - return false; - } - - /** - * Determines if the user can view the IP address in the output either because they are the - * actor that performed the action, or because they are an administrator on the Panel. - */ - protected function canViewIP(Model $actor = null): bool - { - return $actor?->is($this->request->user()) || $this->request->user()?->root_admin; - } -} diff --git a/app/Transformers/Client/BackupTransformer.php b/app/Transformers/Client/BackupTransformer.php deleted file mode 100644 index 7592c7a21b3..00000000000 --- a/app/Transformers/Client/BackupTransformer.php +++ /dev/null @@ -1,39 +0,0 @@ - $backup->uuid, - 'is_successful' => $backup->is_successful, - 'is_locked' => $backup->is_locked, - 'name' => $backup->name, - 'size' => $backup->size, - 'completed_at' => $backup->completed_at, - 'created_at' => $backup->created_at, - ]; - } -} diff --git a/app/Transformers/Client/MediaTransformer.php b/app/Transformers/Client/MediaTransformer.php deleted file mode 100644 index 80994300a28..00000000000 --- a/app/Transformers/Client/MediaTransformer.php +++ /dev/null @@ -1,19 +0,0 @@ - $data['uuid'], - 'name' => $data['name'], - 'size' => $data['size'], - 'hidden' => $data['hidden'], - 'mounted' => $data['mounted'], - ]; - } -} diff --git a/app/Transformers/Client/RenamedServerTransformer.php b/app/Transformers/Client/RenamedServerTransformer.php deleted file mode 100644 index 4a1619e1e32..00000000000 --- a/app/Transformers/Client/RenamedServerTransformer.php +++ /dev/null @@ -1,20 +0,0 @@ - $server->name, - 'hostname' => $server->hostname, - ]; - } -} diff --git a/app/Transformers/Client/ServerBootOrderTransformer.php b/app/Transformers/Client/ServerBootOrderTransformer.php deleted file mode 100644 index 649fd47d602..00000000000 --- a/app/Transformers/Client/ServerBootOrderTransformer.php +++ /dev/null @@ -1,16 +0,0 @@ - $data['unused_devices']->toArray(), - 'boot_order' => $data['boot_order']->toArray(), - ]; - } -} diff --git a/app/Transformers/Client/ServerDetailTransformer.php b/app/Transformers/Client/ServerDetailTransformer.php deleted file mode 100644 index 0d1ad7f2b6e..00000000000 --- a/app/Transformers/Client/ServerDetailTransformer.php +++ /dev/null @@ -1,23 +0,0 @@ -toArray(); - - $data['internal_id'] = $data['id']; - $data['id'] = $data['uuid_short']; - unset($data['uuid_short']); - - return $data; - } -} diff --git a/app/Transformers/Client/ServerNetworkTransformer.php b/app/Transformers/Client/ServerNetworkTransformer.php deleted file mode 100644 index 6a58a7ea09f..00000000000 --- a/app/Transformers/Client/ServerNetworkTransformer.php +++ /dev/null @@ -1,18 +0,0 @@ - $data['nameservers'], - ]; - } -} diff --git a/app/Transformers/Client/ServerSecurityTransformer.php b/app/Transformers/Client/ServerSecurityTransformer.php deleted file mode 100644 index ed620885d83..00000000000 --- a/app/Transformers/Client/ServerSecurityTransformer.php +++ /dev/null @@ -1,18 +0,0 @@ - $data['ssh_keys'], - ]; - } -} diff --git a/app/Transformers/Client/ServerStateTransformer.php b/app/Transformers/Client/ServerStateTransformer.php deleted file mode 100644 index 8c3712f3edb..00000000000 --- a/app/Transformers/Client/ServerStateTransformer.php +++ /dev/null @@ -1,14 +0,0 @@ -toArray(); - } -} diff --git a/app/Transformers/Client/ServerTerminalTransformer.php b/app/Transformers/Client/ServerTerminalTransformer.php deleted file mode 100644 index a6317b09d3f..00000000000 --- a/app/Transformers/Client/ServerTerminalTransformer.php +++ /dev/null @@ -1,22 +0,0 @@ - array_get($data, 'ticket'), - 'node' => array_get($data, 'node'), - 'vmid' => array_get($data, 'vmid'), - 'fqdn' => array_get($data, 'fqdn'), - 'port' => array_get($data, 'port'), - ]; - } -} diff --git a/app/Transformers/Client/ServerTransformer.php b/app/Transformers/Client/ServerTransformer.php deleted file mode 100644 index 98129a391bd..00000000000 --- a/app/Transformers/Client/ServerTransformer.php +++ /dev/null @@ -1,41 +0,0 @@ -getByEloquent($server); - - $data = $serverEloquentData->toArray(); - - $data['internal_id'] = $data['id']; - $data['id'] = $data['uuid_short']; - unset($data['uuid_short']); - - return $data; - } - - public function includeUser(Server $server) - { - return $this->item($server->user, new UserTransformer); - } - - public function includeNode(Server $server) - { - return $this->item($server->node, new NodeTransformer); - } -} diff --git a/app/Transformers/Client/TemplateGroupTransformer.php b/app/Transformers/Client/TemplateGroupTransformer.php deleted file mode 100644 index 97e0a019c9b..00000000000 --- a/app/Transformers/Client/TemplateGroupTransformer.php +++ /dev/null @@ -1,35 +0,0 @@ - $group->uuid, - 'name' => $group->name, - 'hidden' => $group->hidden, - 'order_column' => $group->order_column, - ]; - } - - public function includeTemplates(TemplateGroup $templateGroup) - { - return $this->collection($templateGroup->templates, new TemplateTransformer); - } -} diff --git a/app/Transformers/Client/TemplateTransformer.php b/app/Transformers/Client/TemplateTransformer.php deleted file mode 100644 index a339483fbe0..00000000000 --- a/app/Transformers/Client/TemplateTransformer.php +++ /dev/null @@ -1,19 +0,0 @@ - $template->uuid, - 'name' => $template->name, - 'hidden' => $template->hidden, - 'order_column' => $template->order_column, - ]; - } -} diff --git a/app/Transformers/Client/UserTransformer.php b/app/Transformers/Client/UserTransformer.php deleted file mode 100644 index 422d1d07e6e..00000000000 --- a/app/Transformers/Client/UserTransformer.php +++ /dev/null @@ -1,39 +0,0 @@ - $user->id, - 'name' => $user->name, - 'email' => $user->email, - 'email_verified_at' => $user->email_verified_at, - 'root_admin' => $user->root_admin, - 'created_at' => $user->created_at, - 'updated_at' => $user->updated_at, - ]; - } -} diff --git a/app/Transformers/Coterm/NoVncCredentialsTransformer.php b/app/Transformers/Coterm/NoVncCredentialsTransformer.php deleted file mode 100644 index 018b082417e..00000000000 --- a/app/Transformers/Coterm/NoVncCredentialsTransformer.php +++ /dev/null @@ -1,24 +0,0 @@ - $data['server']->node->fqdn, - 'node_port' => $data['server']->node->port, - 'node_pve_name' => $data['server']->node->cluster, - 'vmid' => $data['server']->vmid, - ...$data['credentials']->toArray(), - ]; - } -} diff --git a/app/Transformers/Coterm/XTermCredentialsTransformer.php b/app/Transformers/Coterm/XTermCredentialsTransformer.php deleted file mode 100644 index d6bff18c01d..00000000000 --- a/app/Transformers/Coterm/XTermCredentialsTransformer.php +++ /dev/null @@ -1,24 +0,0 @@ - $data['server']->node->fqdn, - 'node_port' => $data['server']->node->port, - 'node_pve_name' => $data['server']->node->cluster, - 'vmid' => $data['server']->vmid, - ...$data['credentials']->toArray(), - ]; - } -} diff --git a/app/Validation/ValidateAddressRangeSize.php b/app/Validation/ValidateAddressRangeSize.php deleted file mode 100644 index e1535814943..00000000000 --- a/app/Validation/ValidateAddressRangeSize.php +++ /dev/null @@ -1,53 +0,0 @@ -validated(); - - if (empty($data['starting_address']) || empty($data['ending_address'])) { - return; - } - - if ($this->addressType === AddressType::IPV4) { - $from = ip2long($data['starting_address']); - $to = ip2long($data['ending_address']); - - if ($from === false || $to === false) { - return; - } - - $count = $to - $from + 1; - } else { - $from = ipv6ToInteger($data['starting_address']); - $to = ipv6ToInteger($data['ending_address']); - $count = gmp_intval(gmp_add(gmp_sub($to, $from), 1)); - } - - if ($count < 1) { - $validator->errors()->add('ending_address', __('validation.address_range_order')); - return; - } - - if ($count > self::MAX_ADDRESSES) { - $validator->errors()->add( - 'ending_address', - __('validation.address_range_too_large', [ - 'count' => number_format($count), - 'maximum' => number_format(self::MAX_ADDRESSES), - ]), - ); - } - } -} diff --git a/app/Validation/ValidateAddressType.php b/app/Validation/ValidateAddressType.php index e3c5c7d7c80..87cae46265f 100644 --- a/app/Validation/ValidateAddressType.php +++ b/app/Validation/ValidateAddressType.php @@ -1,25 +1,25 @@ validated(); - if ($this->addressType === AddressType::IPV4) { + if ($this->addressType === AddressVersion::IPv4) { foreach ($this->fields as $field) { if (! filter_var($data[$field], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { $validator->errors()->add('address', __('validation.ipv4', ['attribute' => $field])); } } - } elseif ($this->addressType === AddressType::IPV6) { + } elseif ($this->addressType === AddressVersion::IPv6) { foreach ($this->fields as $field) { if (! filter_var($data[$field], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { $validator->errors()->add('address', __('validation.ipv6', ['attribute' => $field])); @@ -27,4 +27,4 @@ public function __invoke(Validator $validator) } } } -} \ No newline at end of file +} diff --git a/app/Validation/ValidateAddressUniqueness.php b/app/Validation/ValidateAddressUniqueness.php deleted file mode 100644 index 849f4a9affd..00000000000 --- a/app/Validation/ValidateAddressUniqueness.php +++ /dev/null @@ -1,31 +0,0 @@ -validated(); - - if (!$this->existingAddress) { - if (Address::where([['address_pool_id', '=', $this->addressPoolId], ['address', '=', $data['address']]], - )->exists()) { - $validator->errors()->add('address', __('validation.unique_exists', ['attribute' => 'address'])); - } - } else { - if ($this->existingAddress !== $data['address'] && Address::where( - [['address_pool_id', '=', $this->addressPoolId], ['address', '=', $data['address']]], - )->exists()) { - $validator->errors()->add('address', __('validation.unique_exists', ['attribute' => 'address'])); - } - } - } -} \ No newline at end of file diff --git a/artisan b/artisan index 67a3329b183..8e04b42240f 100644 --- a/artisan +++ b/artisan @@ -1,53 +1,15 @@ #!/usr/bin/env php make(Illuminate\Contracts\Console\Kernel::class); - -$status = $kernel->handle( - $input = new Symfony\Component\Console\Input\ArgvInput, - new Symfony\Component\Console\Output\ConsoleOutput -); - -/* -|-------------------------------------------------------------------------- -| Shutdown The Application -|-------------------------------------------------------------------------- -| -| Once Artisan has finished running, we will fire off the shutdown events -| so that any final work may be done by the application before we shut -| down the process. This is the last thing to happen to the request. -| -*/ - -$kernel->terminate($input, $status); +// Bootstrap Laravel and handle the command... +$status = (require_once __DIR__.'/bootstrap/app.php') + ->handleCommand(new ArgvInput); exit($status); diff --git a/bootstrap/app.php b/bootstrap/app.php index e15cce537b5..ec4a7c6b7a9 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,55 +1,102 @@ singleton( - Illuminate\Contracts\Http\Kernel::class, - Convoy\Http\Kernel::class -); - -$app->singleton( - Illuminate\Contracts\Console\Kernel::class, - Convoy\Console\Kernel::class -); - -$app->singleton( - Illuminate\Contracts\Debug\ExceptionHandler::class, - Convoy\Exceptions\Handler::class -); - -/* -|-------------------------------------------------------------------------- -| Return The Application -|-------------------------------------------------------------------------- -| -| This script returns the application instance. The instance is given to -| the calling script so we can separate the building of the instances -| from the actual running of the application and sending responses. -| -*/ - -return $app; +use App\Exceptions\HasErrorCode; +use App\Http\Middleware\AdminAuthenticate; +use App\Http\Middleware\EnforceTokenAbilities; +use App\Http\Middleware\EnforceTokenNetworkRestrictions; +use App\Http\Middleware\RecordSessionActivity; +use App\Http\Middleware\ValidateCsrfToken; +use App\Support\Api\AccountTokenAbilities; +use Illuminate\Foundation\Application; +use Illuminate\Foundation\Configuration\Exceptions; +use Illuminate\Foundation\Configuration\Middleware; +use Illuminate\Http\Request; +use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; + +return Application::configure(basePath: dirname(__DIR__)) + ->withProviders() + ->withRouting( + commands: __DIR__.'/../routes/console.php', + channels: __DIR__.'/../routes/channels.php', + health: '/up', + then: function () { + Route::middleware('web')->group(function () { + Route::prefix('/api/auth') + ->group(base_path('routes/api-auth.php')); + + Route::middleware(['auth.session']) + ->group(base_path('routes/base.php')); + + // The client API accepts both the panel's web session and end-user personal + // access tokens (Sanctum bearer). `web` is tried first, so a session request + // authenticates without an access token (currentAccessToken() === null) and is + // never ability-scoped; a bearer request resolves to a PersonalAccessToken and is. + Route::middleware([ + 'auth:web,sanctum', + EnforceTokenAbilities::class.':'.AccountTokenAbilities::class, + ])->prefix('/api/client') + ->as('client.') + ->scopeBindings() + ->group(base_path('routes/api-client.php')); + + Route::middleware(['auth', AdminAuthenticate::class]) + ->prefix('/api/admin') + ->as('admin.') + ->scopeBindings() + ->group(base_path('routes/api-admin.php')); + }); + + Route::middleware(['api'])->group(function () { + // The Application API (external Bearer-token clients) shares the + // exact same route definitions as the admin panel — one source + // of truth. Session vs. token access is differentiated at the + // guard (auth:sanctum here vs. web session on /api/admin), and + // token-forbidden routes opt out via DenyApiTokenAccess. + Route::middleware([ + 'auth:sanctum', + AdminAuthenticate::class, + EnforceTokenNetworkRestrictions::class, + EnforceTokenAbilities::class, + ]) + ->prefix('/api/application') + ->as('application.') + ->scopeBindings() + ->group(base_path('routes/api-admin.php')); + + Route::prefix('/api/anchor') + ->as('anchor.') + ->group(base_path('routes/api-anchor.php')); + }); + } + ) + ->withMiddleware(function (Middleware $middleware) { + // The client API is served under the web group but also accepts Sanctum bearer tokens; + // our CSRF middleware exempts genuine token requests (which browsers can't forge) while + // keeping full CSRF protection for the session-cookie SPA. + $middleware->replace( + Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, + ValidateCsrfToken::class, + ); + + // Track active web sessions (for the account "active sessions" list). Appended to the web + // group so it runs after the session + auth are resolved; it self-skips token/anon requests. + $middleware->web(append: RecordSessionActivity::class); + }) + ->withExceptions(function (Exceptions $exceptions) { + // Surface a stable, machine-readable `code` for exceptions that opt in + // via HasErrorCode. Nothing is auto-derived from the class name, so a + // fork never leaks an exception it didn't explicitly code. + $exceptions->render(function (HasErrorCode $e, Request $request) { + if (! $request->expectsJson()) { + return null; + } + + $status = $e instanceof HttpExceptionInterface ? $e->getStatusCode() : 400; + $headers = $e instanceof HttpExceptionInterface ? $e->getHeaders() : []; + + return response()->json([ + 'message' => $e->getMessage(), + 'code' => $e->errorCode(), + ], $status, $headers); + }); + })->create(); diff --git a/bootstrap/providers.php b/bootstrap/providers.php new file mode 100644 index 00000000000..800017d9ccd --- /dev/null +++ b/bootstrap/providers.php @@ -0,0 +1,15 @@ +=8.1", - "revolt/event-loop": "^1 || ^0.2" + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^8.1" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "phpunit/phpunit": "^9", - "psalm/phar": "5.23.1" + "phly/keep-a-changelog": "^2.12", + "phpunit/phpunit": "^10.5.11 || ^11.0.4", + "spatie/phpunit-snapshot-assertions": "^5.1.5", + "spatie/pixelmatch-php": "^1.2.0", + "squizlabs/php_codesniffer": "^3.9" + }, + "suggest": { + "ext-imagick": "to generate QR code images" }, "type": "library", "autoload": { - "files": [ - "src/functions.php", - "src/Future/functions.php", - "src/Internal/functions.php" - ], "psr-4": { - "Amp\\": "src" + "BaconQrCode\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-2-Clause" ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - }, - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" } ], - "description": "A non-blocking concurrency framework for PHP applications.", - "homepage": "https://amphp.org/amp", - "keywords": [ - "async", - "asynchronous", - "awaitable", - "concurrency", - "event", - "event-loop", - "future", - "non-blocking", - "promise" - ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", "support": { - "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v3.1.0" + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/v3.1.1" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2025-01-26T16:07:39+00:00" + "time": "2026-04-05T21:06:35+00:00" }, { - "name": "amphp/byte-stream", - "version": "v2.1.2", + "name": "brick/math", + "version": "0.14.8", "source": { "type": "git", - "url": "https://github.com/amphp/byte-stream.git", - "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46" + "url": "https://github.com/brick/math.git", + "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/byte-stream/zipball/55a6bd071aec26fa2a3e002618c20c35e3df1b46", - "reference": "55a6bd071aec26fa2a3e002618c20c35e3df1b46", + "url": "https://api.github.com/repos/brick/math/zipball/63422359a44b7f06cae63c3b429b59e8efcc0629", + "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/parser": "^1.1", - "amphp/pipeline": "^1", - "amphp/serialization": "^1", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2.3" + "php": "^8.2" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "5.22.1" + "php-coveralls/php-coveralls": "^2.2", + "phpstan/phpstan": "2.1.22", + "phpunit/phpunit": "^11.5" }, "type": "library", "autoload": { - "files": [ - "src/functions.php", - "src/Internal/functions.php" - ], "psr-4": { - "Amp\\ByteStream\\": "src" + "Brick\\Math\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A stream abstraction to make working with non-blocking I/O simple.", - "homepage": "https://amphp.org/byte-stream", + "description": "Arbitrary-precision arithmetic library", "keywords": [ - "amp", - "amphp", - "async", - "io", - "non-blocking", - "stream" + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "bignumber", + "brick", + "decimal", + "integer", + "math", + "mathematics", + "rational" ], "support": { - "issues": "https://github.com/amphp/byte-stream/issues", - "source": "https://github.com/amphp/byte-stream/tree/v2.1.2" + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.14.8" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/BenMorel", "type": "github" } ], - "time": "2025-03-16T17:10:27+00:00" + "time": "2026-02-10T14:33:43+00:00" }, { - "name": "amphp/cache", - "version": "v2.0.1", + "name": "carbonphp/carbon-doctrine-types", + "version": "3.2.0", "source": { "type": "git", - "url": "https://github.com/amphp/cache.git", - "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c" + "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/cache/zipball/46912e387e6aa94933b61ea1ead9cf7540b7797c", - "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c", + "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/serialization": "^1", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": "^8.1" + }, + "conflict": { + "doctrine/dbal": "<4.0.0 || >=5.0.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.4" + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" }, "type": "library", "autoload": { "psr-4": { - "Amp\\Cache\\": "src" + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" } }, "notification-url": "https://packagist.org/downloads/", @@ -201,164 +158,121 @@ ], "authors": [ { - "name": "Niklas Keller", - "email": "me@kelunik.com" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" } ], - "description": "A fiber-aware cache API based on Amp and Revolt.", - "homepage": "https://amphp.org/cache", + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], "support": { - "issues": "https://github.com/amphp/cache/issues", - "source": "https://github.com/amphp/cache/tree/v2.0.1" + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/kylekatarnls", "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" } ], - "time": "2024-04-19T03:38:06+00:00" + "time": "2024-02-09T16:56:22+00:00" }, { - "name": "amphp/dns", - "version": "v2.4.0", + "name": "dasprid/enum", + "version": "1.0.7", "source": { "type": "git", - "url": "https://github.com/amphp/dns.git", - "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71" + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/dns/zipball/78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", - "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", + "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/cache": "^2", - "amphp/parser": "^1", - "amphp/process": "^2", - "daverandom/libdns": "^2.0.2", - "ext-filter": "*", - "ext-json": "*", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": ">=7.1 <9.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "5.20" + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "*" }, "type": "library", "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Amp\\Dns\\": "src" + "DASPRiD\\Enum\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-2-Clause" ], "authors": [ { - "name": "Chris Wright", - "email": "addr@daverandom.com" - }, - { - "name": "Daniel Lowrey", - "email": "rdlowrey@php.net" - }, - { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" } ], - "description": "Async DNS resolution for Amp.", - "homepage": "https://github.com/amphp/dns", + "description": "PHP 7.1 enum implementation", "keywords": [ - "amp", - "amphp", - "async", - "client", - "dns", - "resolve" + "enum", + "map" ], "support": { - "issues": "https://github.com/amphp/dns/issues", - "source": "https://github.com/amphp/dns/tree/v2.4.0" + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2025-01-19T15:43:40+00:00" + "time": "2025-09-16T12:23:56+00:00" }, { - "name": "amphp/parallel", - "version": "v2.3.1", + "name": "dflydev/dot-access-data", + "version": "v3.0.3", "source": { "type": "git", - "url": "https://github.com/amphp/parallel.git", - "reference": "5113111de02796a782f5d90767455e7391cca190" + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parallel/zipball/5113111de02796a782f5d90767455e7391cca190", - "reference": "5113111de02796a782f5d90767455e7391cca190", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/cache": "^2", - "amphp/parser": "^1", - "amphp/pipeline": "^1", - "amphp/process": "^2", - "amphp/serialization": "^1", - "amphp/socket": "^2", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1" + "php": "^7.1 || ^8.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.18" + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, "autoload": { - "files": [ - "src/Context/functions.php", - "src/Context/Internal/functions.php", - "src/Ipc/functions.php", - "src/Worker/functions.php" - ], "psr-4": { - "Amp\\Parallel\\": "src" + "Dflydev\\DotAccessData\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -367,130 +281,116 @@ ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" }, { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" }, { - "name": "Stephen Coakley", - "email": "me@stephencoakley.com" + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" } ], - "description": "Parallel processing component for Amp.", - "homepage": "https://github.com/amphp/parallel", + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", "keywords": [ - "async", - "asynchronous", - "concurrent", - "multi-processing", - "multi-threading" + "access", + "data", + "dot", + "notation" ], "support": { - "issues": "https://github.com/amphp/parallel/issues", - "source": "https://github.com/amphp/parallel/tree/v2.3.1" + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-12-21T01:56:09+00:00" + "time": "2024-07-08T12:26:09+00:00" }, { - "name": "amphp/parser", - "version": "v1.1.1", + "name": "doctrine/deprecations", + "version": "1.1.6", "source": { "type": "git", - "url": "https://github.com/amphp/parser.git", - "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parser/zipball/3cf1f8b32a0171d4b1bed93d25617637a77cded7", - "reference": "3cf1f8b32a0171d4b1bed93d25617637a77cded7", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", "shasum": "" }, "require": { - "php": ">=7.4" + "php": "^7.1 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<=7.5 || >=14" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.4" + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", + "phpstan/phpstan-phpunit": "^1.0 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", + "psr/log": "^1 || ^2 || ^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" }, "type": "library", "autoload": { "psr-4": { - "Amp\\Parser\\": "src" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" - } - ], - "description": "A generator parser to make streaming parsers simple.", - "homepage": "https://github.com/amphp/parser", - "keywords": [ - "async", - "non-blocking", - "parser", - "stream" - ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", "support": { - "issues": "https://github.com/amphp/parser/issues", - "source": "https://github.com/amphp/parser/tree/v1.1.1" + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-03-21T19:16:53+00:00" + "time": "2026-02-07T07:09:04+00:00" }, { - "name": "amphp/pipeline", - "version": "v1.2.3", + "name": "doctrine/inflector", + "version": "2.1.0", "source": { "type": "git", - "url": "https://github.com/amphp/pipeline.git", - "reference": "7b52598c2e9105ebcddf247fc523161581930367" + "url": "https://github.com/doctrine/inflector.git", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/pipeline/zipball/7b52598c2e9105ebcddf247fc523161581930367", - "reference": "7b52598c2e9105ebcddf247fc523161581930367", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", "shasum": "" }, "require": { - "amphp/amp": "^3", - "php": ">=8.1", - "revolt/event-loop": "^1" + "php": "^7.2 || ^8.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.18" + "doctrine/coding-standard": "^12.0 || ^13.0", + "phpstan/phpstan": "^1.12 || ^2.0", + "phpstan/phpstan-phpunit": "^1.4 || ^2.0", + "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", + "phpunit/phpunit": "^8.5 || ^12.2" }, "type": "library", "autoload": { "psr-4": { - "Amp\\Pipeline\\": "src" + "Doctrine\\Inflector\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -499,70 +399,88 @@ ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" }, { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "Asynchronous iterators and operators.", - "homepage": "https://amphp.org/pipeline", + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", "keywords": [ - "amp", - "amphp", - "async", - "io", - "iterator", - "non-blocking" + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" ], "support": { - "issues": "https://github.com/amphp/pipeline/issues", - "source": "https://github.com/amphp/pipeline/tree/v1.2.3" + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.1.0" }, "funding": [ { - "url": "https://github.com/amphp", - "type": "github" + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" } ], - "time": "2025-03-16T16:33:53+00:00" + "time": "2025-08-10T19:31:58+00:00" }, { - "name": "amphp/process", - "version": "v2.0.3", + "name": "doctrine/lexer", + "version": "3.0.1", "source": { "type": "git", - "url": "https://github.com/amphp/process.git", - "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d" + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/process/zipball/52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", - "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/sync": "^2", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": "^8.1" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.4" + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" }, "type": "library", "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Amp\\Process\\": "src" + "Doctrine\\Common\\Lexer\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -571,60 +489,81 @@ ], "authors": [ { - "name": "Bob Weinand", - "email": "bobwei9@hotmail.com" + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" }, { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" + "name": "Roman Borschel", + "email": "roman@code-factory.org" }, { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" } ], - "description": "A fiber-aware process manager based on Amp and Revolt.", - "homepage": "https://amphp.org/process", + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], "support": { - "issues": "https://github.com/amphp/process/issues", - "source": "https://github.com/amphp/process/tree/v2.0.3" + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" }, "funding": [ { - "url": "https://github.com/amphp", - "type": "github" + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" } ], - "time": "2024-04-19T03:13:44+00:00" + "time": "2024-02-05T11:56:58+00:00" }, { - "name": "amphp/serialization", - "version": "v1.0.0", + "name": "dragonmantank/cron-expression", + "version": "v3.6.0", "source": { "type": "git", - "url": "https://github.com/amphp/serialization.git", - "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1" + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/serialization/zipball/693e77b2fb0b266c3c7d622317f881de44ae94a1", - "reference": "693e77b2fb0b266c3c7d622317f881de44ae94a1", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013", + "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013", "shasum": "" }, "require": { - "php": ">=7.1" + "php": "^8.2|^8.3|^8.4|^8.5" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "dev-master", - "phpunit/phpunit": "^9 || ^8 || ^7" + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.32|^2.1.31", + "phpunit/phpunit": "^8.5.48|^9.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Amp\\Serialization\\": "src" + "Cron\\": "src/Cron/" } }, "notification-url": "https://packagist.org/downloads/", @@ -633,69 +572,63 @@ ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" } ], - "description": "Serialization tools for IPC and data storage in PHP.", - "homepage": "https://github.com/amphp/serialization", + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", "keywords": [ - "async", - "asynchronous", - "serialization", - "serialize" + "cron", + "schedule" ], "support": { - "issues": "https://github.com/amphp/serialization/issues", - "source": "https://github.com/amphp/serialization/tree/master" + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.6.0" }, - "time": "2020-03-25T21:39:07+00:00" + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2025-10-31T18:51:33+00:00" }, { - "name": "amphp/socket", - "version": "v2.3.1", + "name": "egulias/email-validator", + "version": "4.0.4", "source": { "type": "git", - "url": "https://github.com/amphp/socket.git", - "reference": "58e0422221825b79681b72c50c47a930be7bf1e1" + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/socket/zipball/58e0422221825b79681b72c50c47a930be7bf1e1", - "reference": "58e0422221825b79681b72c50c47a930be7bf1e1", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/byte-stream": "^2", - "amphp/dns": "^2", - "ext-openssl": "*", - "kelunik/certificate": "^1.1", - "league/uri": "^6.5 | ^7", - "league/uri-interfaces": "^2.3 | ^7", + "doctrine/lexer": "^2.0 || ^3.0", "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "symfony/polyfill-intl-idn": "^1.26" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "amphp/process": "^2", - "phpunit/phpunit": "^9", - "psalm/phar": "5.20" + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, "autoload": { - "files": [ - "src/functions.php", - "src/Internal/functions.php", - "src/SocketAddress/functions.php" - ], "psr-4": { - "Amp\\Socket\\": "src" + "Egulias\\EmailValidator\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -704,259 +637,281 @@ ], "authors": [ { - "name": "Daniel Lowrey", - "email": "rdlowrey@gmail.com" - }, - { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Eduardo Gulias Davis" } ], - "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.", - "homepage": "https://github.com/amphp/socket", + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", "keywords": [ - "amp", - "async", - "encryption", - "non-blocking", - "sockets", - "tcp", - "tls" + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" ], "support": { - "issues": "https://github.com/amphp/socket/issues", - "source": "https://github.com/amphp/socket/tree/v2.3.1" + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" }, "funding": [ { - "url": "https://github.com/amphp", + "url": "https://github.com/egulias", "type": "github" } ], - "time": "2024-04-21T14:33:03+00:00" + "time": "2025-03-06T22:45:56+00:00" }, { - "name": "amphp/sync", - "version": "v2.3.0", + "name": "firebase/php-jwt", + "version": "v7.1.0", "source": { "type": "git", - "url": "https://github.com/amphp/sync.git", - "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1" + "url": "https://github.com/googleapis/php-jwt.git", + "reference": "b374a5d1a4f1f67fadc2165cdb284645945e2fc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/sync/zipball/217097b785130d77cfcc58ff583cf26cd1770bf1", - "reference": "217097b785130d77cfcc58ff583cf26cd1770bf1", + "url": "https://api.github.com/repos/googleapis/php-jwt/zipball/b374a5d1a4f1f67fadc2165cdb284645945e2fc0", + "reference": "b374a5d1a4f1f67fadc2165cdb284645945e2fc0", "shasum": "" }, "require": { - "amphp/amp": "^3", - "amphp/pipeline": "^1", - "amphp/serialization": "^1", - "php": ">=8.1", - "revolt/event-loop": "^1 || ^0.2" + "php": "^8.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "amphp/phpunit-util": "^3", - "phpunit/phpunit": "^9", - "psalm/phar": "5.23" + "guzzlehttp/guzzle": "^7.4", + "phpfastcache/phpfastcache": "^9.2", + "phpseclib/phpseclib": "~3.0", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present", + "phpseclib/phpseclib": "Support PS256 (RSASSA-PSS) signatures" }, "type": "library", "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Amp\\Sync\\": "src" + "Firebase\\JWT\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" }, { - "name": "Stephen Coakley", - "email": "me@stephencoakley.com" + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" } ], - "description": "Non-blocking synchronization primitives for PHP based on Amp and Revolt.", - "homepage": "https://github.com/amphp/sync", + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/googleapis/php-jwt", "keywords": [ - "async", - "asynchronous", - "mutex", - "semaphore", - "synchronization" + "jwt", + "php" ], "support": { - "issues": "https://github.com/amphp/sync/issues", - "source": "https://github.com/amphp/sync/tree/v2.3.0" + "issues": "https://github.com/googleapis/php-jwt/issues", + "source": "https://github.com/googleapis/php-jwt/tree/v7.1.0" }, - "funding": [ - { - "url": "https://github.com/amphp", - "type": "github" - } - ], - "time": "2024-08-03T19:31:26+00:00" + "time": "2026-06-11T17:54:14+00:00" }, { - "name": "bacon/bacon-qr-code", - "version": "v3.0.1", + "name": "fruitcake/php-cors", + "version": "v1.4.0", "source": { "type": "git", - "url": "https://github.com/Bacon/BaconQrCode.git", - "reference": "f9cc1f52b5a463062251d666761178dbdb6b544f" + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/f9cc1f52b5a463062251d666761178dbdb6b544f", - "reference": "f9cc1f52b5a463062251d666761178dbdb6b544f", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", "shasum": "" }, "require": { - "dasprid/enum": "^1.0.3", - "ext-iconv": "*", - "php": "^8.1" + "php": "^8.1", + "symfony/http-foundation": "^5.4|^6.4|^7.3|^8" }, "require-dev": { - "phly/keep-a-changelog": "^2.12", - "phpunit/phpunit": "^10.5.11 || 11.0.4", - "spatie/phpunit-snapshot-assertions": "^5.1.5", - "squizlabs/php_codesniffer": "^3.9" - }, - "suggest": { - "ext-imagick": "to generate QR code images" + "phpstan/phpstan": "^2", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, "autoload": { "psr-4": { - "BaconQrCode\\": "src/" + "Fruitcake\\Cors\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-2-Clause" + "MIT" ], "authors": [ { - "name": "Ben Scholzen 'DASPRiD'", - "email": "mail@dasprids.de", - "homepage": "https://dasprids.de/", - "role": "Developer" + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" } ], - "description": "BaconQrCode is a QR code generator for PHP.", - "homepage": "https://github.com/Bacon/BaconQrCode", + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], "support": { - "issues": "https://github.com/Bacon/BaconQrCode/issues", - "source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.1" + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.4.0" }, - "time": "2024-10-01T13:55:55+00:00" - }, - { - "name": "brick/math", - "version": "0.14.8", + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2025-12-03T09:33:47+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.4", "source": { "type": "git", - "url": "https://github.com/brick/math.git", - "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629" + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/63422359a44b7f06cae63c3b429b59e8efcc0629", - "reference": "63422359a44b7f06cae63c3b429b59e8efcc0629", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", + "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", "shasum": "" }, "require": { - "php": "^8.2" + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.5" }, "require-dev": { - "php-coveralls/php-coveralls": "^2.2", - "phpstan/phpstan": "2.1.22", - "phpunit/phpunit": "^11.5" + "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" }, "type": "library", "autoload": { "psr-4": { - "Brick\\Math\\": "src/" + "GrahamCampbell\\ResultType\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Arbitrary-precision arithmetic library", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", "keywords": [ - "Arbitrary-precision", - "BigInteger", - "BigRational", - "arithmetic", - "bigdecimal", - "bignum", - "bignumber", - "brick", - "decimal", - "integer", - "math", - "mathematics", - "rational" + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" ], "support": { - "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.8" + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4" }, "funding": [ { - "url": "https://github.com/BenMorel", + "url": "https://github.com/GrahamCampbell", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" } ], - "time": "2026-02-10T14:33:43+00:00" + "time": "2025-12-27T19:43:20+00:00" }, { - "name": "carbonphp/carbon-doctrine-types", - "version": "3.2.0", + "name": "guzzlehttp/guzzle", + "version": "7.10.5", "source": { "type": "git", - "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" + "url": "https://github.com/guzzle/guzzle.git", + "reference": "7c8d84b39e680315f687e8662a9d6fb0865c5148" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7c8d84b39e680315f687e8662a9d6fb0865c5148", + "reference": "7c8d84b39e680315f687e8662a9d6fb0865c5148", "shasum": "" }, "require": { - "php": "^8.1" + "ext-json": "*", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" }, - "conflict": { - "doctrine/dbal": "<4.0.0 || >=5.0.0" + "provide": { + "psr/http-client-implementation": "1.0" }, "require-dev": { - "doctrine/dbal": "^4.0.0", - "nesbot/carbon": "^2.71.0 || ^3.0.0", - "phpunit/phpunit": "^10.3" + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "guzzlehttp/test-server": "^0.4", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { + "files": [ + "src/functions_include.php" + ], "psr-4": { - "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + "GuzzleHttp\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -965,165 +920,306 @@ ], "authors": [ { - "name": "KyleKatarn", - "email": "kylekatarnls@gmail.com" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], - "description": "Types to use Carbon in Doctrine", + "description": "Guzzle is a PHP HTTP client library", "keywords": [ - "carbon", - "date", - "datetime", - "doctrine", - "time" + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" ], "support": { - "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", - "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.10.5" }, "funding": [ { - "url": "https://github.com/kylekatarnls", + "url": "https://github.com/GrahamCampbell", "type": "github" }, { - "url": "https://opencollective.com/Carbon", - "type": "open_collective" + "url": "https://github.com/Nyholm", + "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", "type": "tidelift" } ], - "time": "2024-02-09T16:56:22+00:00" + "time": "2026-05-27T11:53:46+00:00" }, { - "name": "dasprid/enum", - "version": "1.0.6", + "name": "guzzlehttp/promises", + "version": "2.4.1", "source": { "type": "git", - "url": "https://github.com/DASPRiD/Enum.git", - "reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90" + "url": "https://github.com/guzzle/promises.git", + "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/8dfd07c6d2cf31c8da90c53b83c026c7696dda90", - "reference": "8dfd07c6d2cf31c8da90c53b83c026c7696dda90", + "url": "https://api.github.com/repos/guzzle/promises/zipball/09e8a212562fb1fb6a512c4156ed71525969d6c2", + "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2", "shasum": "" }, "require": { - "php": ">=7.1 <9.0" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", - "squizlabs/php_codesniffer": "*" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { "psr-4": { - "DASPRiD\\Enum\\": "src/" + "GuzzleHttp\\Promise\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-2-Clause" + "MIT" ], "authors": [ { - "name": "Ben Scholzen 'DASPRiD'", - "email": "mail@dasprids.de", - "homepage": "https://dasprids.de/", - "role": "Developer" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], - "description": "PHP 7.1 enum implementation", + "description": "Guzzle promises library", "keywords": [ - "enum", - "map" + "promise" ], "support": { - "issues": "https://github.com/DASPRiD/Enum/issues", - "source": "https://github.com/DASPRiD/Enum/tree/1.0.6" + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.4.1" }, - "time": "2024-08-09T14:30:48+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2026-05-20T22:57:30+00:00" }, { - "name": "daverandom/libdns", - "version": "v2.1.0", + "name": "guzzlehttp/psr7", + "version": "2.10.3", "source": { "type": "git", - "url": "https://github.com/DaveRandom/LibDNS.git", - "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a" + "url": "https://github.com/guzzle/psr7.git", + "reference": "7c1472269227dc6f18930bd903d7a88fe6c52130" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", - "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/7c1472269227dc6f18930bd903d7a88fe6c52130", + "reference": "7c1472269227dc6f18930bd903d7a88fe6c52130", "shasum": "" }, "require": { - "ext-ctype": "*", - "php": ">=7.1" + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "1.1.0", + "jshttp/mime-db": "1.54.0.1", + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, "suggest": { - "ext-intl": "Required for IDN support" + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "LibDNS\\": "src/" + "GuzzleHttp\\Psr7\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "DNS protocol implementation written in pure PHP", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ - "dns" + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" ], "support": { - "issues": "https://github.com/DaveRandom/LibDNS/issues", - "source": "https://github.com/DaveRandom/LibDNS/tree/v2.1.0" + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.10.3" }, - "time": "2024-04-12T12:12:48+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2026-05-27T11:48:20+00:00" }, { - "name": "dflydev/dot-access-data", - "version": "v3.0.3", + "name": "guzzlehttp/uri-template", + "version": "v1.0.6", "source": { "type": "git", - "url": "https://github.com/dflydev/dflydev-dot-access-data.git", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" + "url": "https://github.com/guzzle/uri-template.git", + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", - "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/eef7f87bab6f204eba3c39224d8075c70c637946", + "reference": "eef7f87bab6f204eba3c39224d8075c70c637946", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" }, "require-dev": { - "phpstan/phpstan": "^0.12.42", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", - "scrutinizer/ocular": "1.6.0", - "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "^4.0.0" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", + "uri-template/tests": "1.0.0" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.x-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { "psr-4": { - "Dflydev\\DotAccessData\\": "src/" + "GuzzleHttp\\UriTemplate\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1132,116 +1228,136 @@ ], "authors": [ { - "name": "Dragonfly Development Inc.", - "email": "info@dflydev.com", - "homepage": "http://dflydev.com" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" }, { - "name": "Beau Simensen", - "email": "beau@dflydev.com", - "homepage": "http://beausimensen.com" + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" }, { - "name": "Carlos Frutos", - "email": "carlos@kiwing.it", - "homepage": "https://github.com/cfrutos" + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" }, { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com" + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" } ], - "description": "Given a deep data structure, access data by dot notation.", - "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "description": "A polyfill class for uri_template of PHP", "keywords": [ - "access", - "data", - "dot", - "notation" + "guzzlehttp", + "uri-template" ], "support": { - "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", - "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.6" }, - "time": "2024-07-08T12:26:09+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2026-05-23T22:00:21+00:00" }, { - "name": "doctrine/deprecations", - "version": "1.1.6", + "name": "jetbrains/phpstorm-stubs", + "version": "v2026.1", "source": { "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" + "url": "https://github.com/JetBrains/phpstorm-stubs", + "reference": "2cdd054c4109dfb76667c9198bf9427606354243" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", - "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/2cdd054c4109dfb76667c9198bf9427606354243", + "reference": "2cdd054c4109dfb76667c9198bf9427606354243", "shasum": "" }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "phpunit/phpunit": "<=7.5 || >=14" - }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^14", - "phpstan/phpstan": "1.4.10 || 2.1.30", - "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", - "psr/log": "^1 || ^2 || ^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + "friendsofphp/php-cs-fixer": "^v3.86", + "nikic/php-parser": "^v5.6", + "phpdocumentor/reflection-docblock": "^5.6", + "phpunit/phpunit": "^12.3" }, "type": "library", "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "src" - } + "files": [ + "PhpStormStubsMap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "Apache-2.0" ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.6" - }, - "time": "2026-02-07T07:09:04+00:00" + "description": "PHP runtime & extensions header files for PhpStorm", + "homepage": "https://www.jetbrains.com/phpstorm", + "keywords": [ + "autocomplete", + "code", + "inference", + "inspection", + "jetbrains", + "phpstorm", + "stubs", + "type" + ], + "time": "2026-02-19T20:12:01+00:00" }, { - "name": "doctrine/inflector", - "version": "2.1.0", + "name": "laravel/fortify", + "version": "v1.37.2", "source": { "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" + "url": "https://github.com/laravel/fortify.git", + "reference": "5d4b6a53527edd19ecc4f13e8e74ec91bdefab0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", + "url": "https://api.github.com/repos/laravel/fortify/zipball/5d4b6a53527edd19ecc4f13e8e74ec91bdefab0c", + "reference": "5d4b6a53527edd19ecc4f13e8e74ec91bdefab0c", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "bacon/bacon-qr-code": "^3.0", + "ext-json": "*", + "illuminate/console": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", + "laravel/passkeys": "^0.2.0", + "php": "^8.2", + "pragmarx/google2fa": "^9.0" }, "require-dev": { - "doctrine/coding-standard": "^12.0 || ^13.0", - "phpstan/phpstan": "^1.12 || ^2.0", - "phpstan/phpstan-phpunit": "^1.4 || ^2.0", - "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", - "phpunit/phpunit": "^8.5 || ^12.2" + "orchestra/testbench": "^9.15|^10.8|^11.0", + "phpstan/phpstan": "^1.10" }, "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Fortify\\FortifyServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "1.x-dev" + } + }, "autoload": { "psr-4": { - "Doctrine\\Inflector\\": "src" + "Laravel\\Fortify\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1250,88 +1366,219 @@ ], "authors": [ { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", - "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "description": "Backend controllers and scaffolding for Laravel authentication.", "keywords": [ - "inflection", - "inflector", - "lowercase", - "manipulation", - "php", - "plural", - "singular", - "strings", - "uppercase", - "words" + "auth", + "laravel" ], "support": { - "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.1.0" + "issues": "https://github.com/laravel/fortify/issues", + "source": "https://github.com/laravel/fortify" }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", - "type": "tidelift" - } - ], - "time": "2025-08-10T19:31:58+00:00" + "time": "2026-05-15T22:59:10+00:00" }, { - "name": "doctrine/lexer", - "version": "3.0.1", + "name": "laravel/framework", + "version": "v12.61.0", "source": { "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + "url": "https://github.com/laravel/framework.git", + "reference": "1124062a1ca92d290c8bcb9b7f649920fa6816bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", - "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "url": "https://api.github.com/repos/laravel/framework/zipball/1124062a1ca92d290c8bcb9b7f649920fa6816bf", + "reference": "1124062a1ca92d290c8bcb9b7f649920fa6816bf", "shasum": "" }, "require": { - "php": "^8.1" + "brick/math": "^0.11|^0.12|^0.13|^0.14", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.4", + "egulias/email-validator": "^3.2.1|^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8.2", + "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.3.0", + "laravel/serializable-closure": "^1.3|^2.0", + "league/commonmark": "^2.8.1", + "league/flysystem": "^3.25.1", + "league/flysystem-local": "^3.25.1", + "league/uri": "^7.5.1", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^3.8.4", + "nunomaduro/termwind": "^2.0", + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^7.2.0", + "symfony/error-handler": "^7.2.0", + "symfony/finder": "^7.2.0", + "symfony/http-foundation": "^7.2.0", + "symfony/http-kernel": "^7.2.0", + "symfony/mailer": "^7.2.0", + "symfony/mime": "^7.2.0", + "symfony/polyfill-php83": "^1.33", + "symfony/polyfill-php84": "^1.34", + "symfony/polyfill-php85": "^1.34", + "symfony/process": "^7.2.0", + "symfony/routing": "^7.2.0", + "symfony/uid": "^7.2.0", + "symfony/var-dumper": "^7.2.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.6.1", + "voku/portable-ascii": "^2.0.2" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/log-implementation": "1.0|2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/concurrency": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/json-schema": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/reflection": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version", + "spatie/once": "*" }, "require-dev": { - "doctrine/coding-standard": "^12", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^5.21" + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.322.9", + "ext-gmp": "*", + "fakerphp/faker": "^1.24", + "guzzlehttp/promises": "^2.0.3", + "guzzlehttp/psr7": "^2.4", + "laravel/pint": "^1.18", + "league/flysystem-aws-s3-v3": "^3.25.1", + "league/flysystem-ftp": "^3.25.1", + "league/flysystem-path-prefixing": "^3.25.1", + "league/flysystem-read-only": "^3.25.1", + "league/flysystem-sftp-v3": "^3.25.1", + "mockery/mockery": "^1.6.10", + "opis/json-schema": "^2.4.1", + "orchestra/testbench-core": "^10.9.0", + "pda/pheanstalk": "^5.0.6|^7.0.0", + "php-http/discovery": "^1.15", + "phpstan/phpstan": "^2.1.41", + "phpunit/phpunit": "^10.5.35|^11.5.3|^12.0.1", + "predis/predis": "^2.3|^3.0", + "resend/resend-php": "^0.10.0|^1.0", + "symfony/cache": "^7.2.0", + "symfony/http-client": "^7.2.0", + "symfony/psr-http-message-bridge": "^7.2.0", + "symfony/translation": "^7.2.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", + "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).", + "fakerphp/faker": "Required to generate fake data using the fake() helper (^1.23).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", + "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", + "mockery/mockery": "Required to use mocking (^1.6).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", + "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", + "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.5.3|^12.0.1).", + "predis/predis": "Required to use the predis connector (^2.3|^3.0).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0|^1.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.2).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.2).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.2).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.2).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.2).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)." }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "12.x-dev" + } + }, "autoload": { + "files": [ + "src/Illuminate/Collections/functions.php", + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Filesystem/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Log/functions.php", + "src/Illuminate/Reflection/helpers.php", + "src/Illuminate/Support/functions.php", + "src/Illuminate/Support/helpers.php" + ], "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/", + "src/Illuminate/Reflection/" + ] } }, "notification-url": "https://packagist.org/downloads/", @@ -1340,81 +1587,136 @@ ], "authors": [ { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" + "framework", + "laravel" ], "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/3.0.1" + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, + "time": "2026-05-26T23:41:33+00:00" + }, + { + "name": "laravel/helpers", + "version": "v1.8.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/helpers.git", + "reference": "5915be977c7cc05fe2498d561b8c026ee56567dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/helpers/zipball/5915be977c7cc05fe2498d561b8c026ee56567dd", + "reference": "5915be977c7cc05fe2498d561b8c026ee56567dd", + "shasum": "" + }, + "require": { + "illuminate/support": "~5.8.0|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "php": "^7.2.0|^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^7.0|^8.0|^9.0|^10.0|^11.0|^12.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" }, { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" + "name": "Dries Vints", + "email": "dries@laravel.com" } ], - "time": "2024-02-05T11:56:58+00:00" + "description": "Provides backwards compatibility for helpers in the latest Laravel release.", + "keywords": [ + "helpers", + "laravel" + ], + "support": { + "source": "https://github.com/laravel/helpers/tree/v1.8.3" + }, + "time": "2026-03-17T16:40:11+00:00" }, { - "name": "dragonmantank/cron-expression", - "version": "v3.6.0", + "name": "laravel/horizon", + "version": "v5.47.1", "source": { "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013" + "url": "https://github.com/laravel/horizon.git", + "reference": "356e3ec86321361a4cb8259cb73fdb3406fa3b30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013", - "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013", + "url": "https://api.github.com/repos/laravel/horizon/zipball/356e3ec86321361a4cb8259cb73fdb3406fa3b30", + "reference": "356e3ec86321361a4cb8259cb73fdb3406fa3b30", "shasum": "" }, "require": { - "php": "^8.2|^8.3|^8.4|^8.5" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" + "ext-json": "*", + "ext-pcntl": "*", + "ext-posix": "*", + "illuminate/contracts": "^9.21|^10.0|^11.0|^12.0|^13.0", + "illuminate/queue": "^9.21|^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^9.21|^10.0|^11.0|^12.0|^13.0", + "laravel/sentinel": "^1.0", + "nesbot/carbon": "^2.17|^3.0", + "php": "^8.0", + "ramsey/uuid": "^4.0", + "symfony/console": "^6.0|^7.0|^8.0", + "symfony/error-handler": "^6.0|^7.0|^8.0", + "symfony/polyfill-php83": "^1.28", + "symfony/process": "^6.0|^7.0|^8.0" }, "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.32|^2.1.31", - "phpunit/phpunit": "^8.5.48|^9.0" + "mockery/mockery": "^1.0", + "orchestra/testbench": "^7.56|^8.37|^9.16|^10.9|^11.0", + "phpstan/phpstan": "^1.10|^2.0", + "predis/predis": "^1.1|^2.0|^3.0" + }, + "suggest": { + "ext-redis": "Required to use the Redis PHP driver.", + "predis/predis": "Required when not using the Redis PHP driver (^1.1|^2.0|^3.0)." }, "type": "library", "extra": { + "laravel": { + "aliases": { + "Horizon": "Laravel\\Horizon\\Horizon" + }, + "providers": [ + "Laravel\\Horizon\\HorizonServiceProvider" + ] + }, "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "6.x-dev" } }, "autoload": { "psr-4": { - "Cron\\": "src/Cron/" + "Laravel\\Horizon\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1423,127 +1725,187 @@ ], "authors": [ { - "name": "Chris Tankersley", - "email": "chris@ctankersley.com", - "homepage": "https://github.com/dragonmantank" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "description": "Dashboard and code-driven configuration for Laravel queues.", "keywords": [ - "cron", - "schedule" + "laravel", + "queue" ], "support": { - "issues": "https://github.com/dragonmantank/cron-expression/issues", - "source": "https://github.com/dragonmantank/cron-expression/tree/v3.6.0" + "issues": "https://github.com/laravel/horizon/issues", + "source": "https://github.com/laravel/horizon/tree/v5.47.1" }, - "funding": [ + "time": "2026-05-20T12:12:55+00:00" + }, + { + "name": "laravel/passkeys", + "version": "v0.2.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/passkeys-server.git", + "reference": "a76656ada41b2b4a591f075eddae5ddc67e8ab9c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/passkeys-server/zipball/a76656ada41b2b4a591f075eddae5ddc67e8ab9c", + "reference": "a76656ada41b2b4a591f075eddae5ddc67e8ab9c", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^11.0|^12.0|^13.0", + "illuminate/database": "^11.0|^12.0|^13.0", + "illuminate/http": "^11.0|^12.0|^13.0", + "illuminate/routing": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", + "php": "^8.2", + "web-auth/webauthn-lib": "5.3.x" + }, + "require-dev": { + "laravel/pint": "^1.28.0", + "orchestra/testbench": "^9.0|^10.0|^11.0", + "pestphp/pest": "^3.0|^4.0", + "phpstan/phpstan": "^2.0", + "rector/rector": "^2.3" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Passkeys\\PasskeysServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Passkeys\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://github.com/dragonmantank", - "type": "github" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "time": "2025-10-31T18:51:33+00:00" + "description": "Passwordless authentication using WebAuthn/passkeys for Laravel", + "homepage": "https://github.com/laravel/passkeys-server", + "keywords": [ + "Authentication", + "Passwordless", + "laravel", + "passkeys", + "webauthn" + ], + "support": { + "issues": "https://github.com/laravel/passkeys-server/issues", + "source": "https://github.com/laravel/passkeys-server" + }, + "time": "2026-05-18T16:26:00+00:00" }, { - "name": "egulias/email-validator", - "version": "4.0.4", + "name": "laravel/prompts", + "version": "v0.3.18", "source": { "type": "git", - "url": "https://github.com/egulias/EmailValidator.git", - "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + "url": "https://github.com/laravel/prompts.git", + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", - "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "url": "https://api.github.com/repos/laravel/prompts/zipball/a19af51bb144bf87f08397921fa619f85c7d4e72", + "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72", "shasum": "" }, "require": { - "doctrine/lexer": "^2.0 || ^3.0", - "php": ">=8.1", - "symfony/polyfill-intl-idn": "^1.26" + "composer-runtime-api": "^2.2", + "ext-mbstring": "*", + "php": "^8.1", + "symfony/console": "^6.2|^7.0|^8.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" }, "require-dev": { - "phpunit/phpunit": "^10.2", - "vimeo/psalm": "^5.12" + "illuminate/collections": "^10.0|^11.0|^12.0|^13.0", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3|^3.4|^4.0", + "phpstan/phpstan": "^1.12.28", + "phpstan/phpstan-mockery": "^1.1.3" }, "suggest": { - "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + "ext-pcntl": "Required for the spinner to be animated." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-main": "0.3.x-dev" } }, "autoload": { + "files": [ + "src/helpers.php" + ], "psr-4": { - "Egulias\\EmailValidator\\": "src" + "Laravel\\Prompts\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Eduardo Gulias Davis" - } - ], - "description": "A library for validating emails against several RFCs", - "homepage": "https://github.com/egulias/EmailValidator", - "keywords": [ - "email", - "emailvalidation", - "emailvalidator", - "validation", - "validator" - ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", "support": { - "issues": "https://github.com/egulias/EmailValidator/issues", - "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.3.18" }, - "funding": [ - { - "url": "https://github.com/egulias", - "type": "github" - } - ], - "time": "2025-03-06T22:45:56+00:00" + "time": "2026-05-19T00:47:18+00:00" }, { - "name": "fruitcake/php-cors", - "version": "v1.4.0", + "name": "laravel/sanctum", + "version": "v4.3.2", "source": { "type": "git", - "url": "https://github.com/fruitcake/php-cors.git", - "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379" + "url": "https://github.com/laravel/sanctum.git", + "reference": "2a9bccc18e9907808e0018dd15fa643937886b1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", - "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/2a9bccc18e9907808e0018dd15fa643937886b1e", + "reference": "2a9bccc18e9907808e0018dd15fa643937886b1e", "shasum": "" }, "require": { - "php": "^8.1", - "symfony/http-foundation": "^5.4|^6.4|^7.3|^8" + "ext-json": "*", + "illuminate/console": "^11.0|^12.0|^13.0", + "illuminate/contracts": "^11.0|^12.0|^13.0", + "illuminate/database": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", + "php": "^8.2", + "symfony/console": "^7.0|^8.0" }, "require-dev": { - "phpstan/phpstan": "^2", - "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^4" + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.15|^10.8|^11.0", + "phpstan/phpstan": "^1.10" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.3-dev" + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] } }, "autoload": { "psr-4": { - "Fruitcake\\Cors\\": "src/" + "Laravel\\Sanctum\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1552,62 +1914,57 @@ ], "authors": [ { - "name": "Fruitcake", - "homepage": "https://fruitcake.nl" - }, - { - "name": "Barryvdh", - "email": "barryvdh@gmail.com" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", - "homepage": "https://github.com/fruitcake/php-cors", + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", "keywords": [ - "cors", + "auth", "laravel", - "symfony" + "sanctum" ], "support": { - "issues": "https://github.com/fruitcake/php-cors/issues", - "source": "https://github.com/fruitcake/php-cors/tree/v1.4.0" + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" }, - "funding": [ - { - "url": "https://fruitcake.nl", - "type": "custom" - }, - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2025-12-03T09:33:47+00:00" + "time": "2026-04-30T11:46:25+00:00" }, { - "name": "graham-campbell/result-type", - "version": "v1.1.4", + "name": "laravel/sentinel", + "version": "v1.1.0", "source": { "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" + "url": "https://github.com/laravel/sentinel.git", + "reference": "972d9885d9d14312a118e9565c4e6ecc5e751ea1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", - "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", + "url": "https://api.github.com/repos/laravel/sentinel/zipball/972d9885d9d14312a118e9565c4e6ecc5e751ea1", + "reference": "972d9885d9d14312a118e9565c4e6ecc5e751ea1", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.5" + "ext-json": "*", + "illuminate/container": "^8.37|^9.0|^10.0|^11.0|^12.0|^13.0", + "php": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" + "laravel/pint": "^1.27", + "orchestra/testbench": "^6.47.1|^7.56|^8.37|^9.16|^10.9|^11.0", + "phpstan/phpstan": "^2.1.33" }, "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sentinel\\SentinelServiceProvider" + ] + } + }, "autoload": { "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" + "Laravel\\Sentinel\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1616,193 +1973,128 @@ ], "authors": [ { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "An Implementation Of The Result Type", - "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" - ], - "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.4" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" }, { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" + "name": "Mior Muhammad Zaki", + "email": "mior@laravel.com" } ], - "time": "2025-12-27T19:43:20+00:00" + "support": { + "source": "https://github.com/laravel/sentinel/tree/v1.1.0" + }, + "time": "2026-03-24T14:03:38+00:00" }, { - "name": "guzzlehttp/guzzle", - "version": "7.10.5", + "name": "laravel/serializable-closure", + "version": "v2.0.13", "source": { "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "7c8d84b39e680315f687e8662a9d6fb0865c5148" + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7c8d84b39e680315f687e8662a9d6fb0865c5148", - "reference": "7c8d84b39e680315f687e8662a9d6fb0865c5148", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce", "shasum": "" }, "require": { - "ext-json": "*", - "guzzlehttp/promises": "^2.3", - "guzzlehttp/psr7": "^2.8", - "php": "^7.2.5 || ^8.0", - "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" - }, - "provide": { - "psr/http-client-implementation": "1.0" + "php": "^8.1" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-curl": "*", - "guzzle/client-integration-tests": "3.0.2", - "guzzlehttp/test-server": "^0.4", - "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.52 || ^9.6.34", - "psr/log": "^1.1 || ^2.0 || ^3.0" - }, - "suggest": { - "ext-curl": "Required for CURL handler support", - "ext-intl": "Required for Internationalized Domain Name (IDN) support", - "psr/log": "Required for using the Log middleware" + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", + "nesbot/carbon": "^2.67|^3.0", + "pestphp/pest": "^2.36|^3.0|^4.0", + "phpstan/phpstan": "^2.0", + "symfony/var-dumper": "^6.2.0|^7.0.0|^8.0.0" }, "type": "library", "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false + "branch-alias": { + "dev-master": "2.x-dev" } }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { - "GuzzleHttp\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Jeremy Lindblom", - "email": "jeremeamia@gmail.com", - "homepage": "https://github.com/jeremeamia" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" + "Laravel\\SerializableClosure\\": "src/" } - ], - "description": "Guzzle is a PHP HTTP client library", - "keywords": [ - "client", - "curl", - "framework", - "http", - "http client", - "psr-18", - "psr-7", - "rest", - "web service" - ], - "support": { - "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.10.5" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://github.com/Nyholm", - "type": "github" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" }, { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", - "type": "tidelift" + "name": "Nuno Maduro", + "email": "nuno@laravel.com" } ], - "time": "2026-05-27T11:53:46+00:00" + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2026-04-16T14:03:50+00:00" }, { - "name": "guzzlehttp/promises", - "version": "2.4.1", + "name": "laravel/socialite", + "version": "v5.28.0", "source": { "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2" + "url": "https://github.com/laravel/socialite.git", + "reference": "4c131ff4b24d8881a9c8fe4eecb5ffeff9803f26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/09e8a212562fb1fb6a512c4156ed71525969d6c2", - "reference": "09e8a212562fb1fb6a512c4156ed71525969d6c2", + "url": "https://api.github.com/repos/laravel/socialite/zipball/4c131ff4b24d8881a9c8fe4eecb5ffeff9803f26", + "reference": "4c131ff4b24d8881a9c8fe4eecb5ffeff9803f26", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0" + "ext-json": "*", + "firebase/php-jwt": "^6.4|^7.0", + "guzzlehttp/guzzle": "^6.0|^7.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0", + "league/oauth1-client": "^1.11", + "php": "^7.2|^8.0", + "phpseclib/phpseclib": "^3.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.52 || ^9.6.34" + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.18|^5.20|^6.47|^7.55|^8.36|^9.15|^10.8|^11.0", + "phpstan/phpstan": "^1.12.23", + "phpunit/phpunit": "^8.0|^9.3|^10.4|^11.5|^12.0" }, "type": "library", "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false + "laravel": { + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + }, + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "GuzzleHttp\\Promise\\": "src/" + "Laravel\\Socialite\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1811,93 +2103,63 @@ ], "authors": [ { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "Guzzle promises library", + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "homepage": "https://laravel.com", "keywords": [ - "promise" + "laravel", + "oauth" ], "support": { - "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.4.1" + "issues": "https://github.com/laravel/socialite/issues", + "source": "https://github.com/laravel/socialite" }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", - "type": "tidelift" - } - ], - "time": "2026-05-20T22:57:30+00:00" + "time": "2026-06-12T03:24:05+00:00" }, { - "name": "guzzlehttp/psr7", - "version": "2.10.3", + "name": "laravel/tinker", + "version": "v2.11.1", "source": { "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "7c1472269227dc6f18930bd903d7a88fe6c52130" + "url": "https://github.com/laravel/tinker.git", + "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/7c1472269227dc6f18930bd903d7a88fe6c52130", - "reference": "7c1472269227dc6f18930bd903d7a88fe6c52130", + "url": "https://api.github.com/repos/laravel/tinker/zipball/c9f80cc835649b5c1842898fb043f8cc098dd741", + "reference": "c9f80cc835649b5c1842898fb043f8cc098dd741", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" - }, - "provide": { - "psr/http-factory-implementation": "1.0", - "psr/http-message-implementation": "1.0" + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.11.1|^0.12.0", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0|^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "1.1.0", - "jshttp/mime-db": "1.54.0.1", - "phpunit/phpunit": "^8.5.52 || ^9.6.34" + "mockery/mockery": "~1.3.3|^1.4.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5.8|^9.3.3|^10.0" }, "suggest": { - "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0)." }, "type": "library", "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] } }, "autoload": { "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" + "Laravel\\Tinker\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1906,528 +2168,400 @@ ], "authors": [ { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://github.com/sagikazarmark" - }, - { - "name": "Tobias Schultze", - "email": "webmaster@tubo-world.de", - "homepage": "https://github.com/Tobion" - }, - { - "name": "Márk Sági-Kazár", - "email": "mark.sagikazar@gmail.com", - "homepage": "https://sagikazarmark.hu" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "description": "PSR-7 message implementation that also provides common utility methods", + "description": "Powerful REPL for the Laravel framework.", "keywords": [ - "http", - "message", - "psr-7", - "request", - "response", - "stream", - "uri", - "url" + "REPL", + "Tinker", + "laravel", + "psysh" ], "support": { - "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.10.3" + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.11.1" }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", - "type": "tidelift" - } - ], - "time": "2026-05-27T11:48:20+00:00" + "time": "2026-02-06T14:12:35+00:00" }, { - "name": "guzzlehttp/uri-template", - "version": "v1.0.6", + "name": "laravel/wayfinder", + "version": "v0.1.20", "source": { "type": "git", - "url": "https://github.com/guzzle/uri-template.git", - "reference": "eef7f87bab6f204eba3c39224d8075c70c637946" + "url": "https://github.com/laravel/wayfinder.git", + "reference": "91d958a6f99fe9187c6eda84e62aa93d79330be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/eef7f87bab6f204eba3c39224d8075c70c637946", - "reference": "eef7f87bab6f204eba3c39224d8075c70c637946", + "url": "https://api.github.com/repos/laravel/wayfinder/zipball/91d958a6f99fe9187c6eda84e62aa93d79330be5", + "reference": "91d958a6f99fe9187c6eda84e62aa93d79330be5", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0", - "symfony/polyfill-php80": "^1.24" + "illuminate/console": "^11.0|^12.0|^13.0", + "illuminate/filesystem": "^11.0|^12.0|^13.0", + "illuminate/routing": "^11.0|^12.0|^13.0", + "illuminate/support": "^11.0|^12.0|^13.0", + "php": "^8.2", + "phpstan/phpdoc-parser": "^2.3" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.52 || ^9.6.34", - "uri-template/tests": "1.0.0" + "laravel/pint": "^1.21", + "orchestra/testbench": "^11.0|^10.1|^9.0" }, "type": "library", "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false + "laravel": { + "providers": [ + "Laravel\\Wayfinder\\WayfinderServiceProvider" + ] } }, "autoload": { "psr-4": { - "GuzzleHttp\\UriTemplate\\": "src" + "Laravel\\Wayfinder\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com", - "homepage": "https://github.com/mtdowling" - }, - { - "name": "George Mponos", - "email": "gmponos@gmail.com", - "homepage": "https://github.com/gmponos" - }, - { - "name": "Tobias Nyholm", - "email": "tobias.nyholm@gmail.com", - "homepage": "https://github.com/Nyholm" - } - ], - "description": "A polyfill class for uri_template of PHP", - "keywords": [ - "guzzlehttp", - "uri-template" - ], - "support": { - "issues": "https://github.com/guzzle/uri-template/issues", - "source": "https://github.com/guzzle/uri-template/tree/v1.0.6" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, + ], + "authors": [ { - "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", - "type": "tidelift" + "name": "Taylor Otwell", + "email": "taylor@laravel.com" } ], - "time": "2026-05-23T22:00:21+00:00" + "description": "Generate TypeScript representations of your Laravel actions and routes.", + "homepage": "https://github.com/laravel/wayfinder", + "keywords": [ + "laravel", + "php", + "routes", + "typescript" + ], + "support": { + "issues": "https://github.com/laravel/wayfinder/issues", + "source": "https://github.com/laravel/wayfinder" + }, + "time": "2026-05-12T01:44:17+00:00" }, { - "name": "kelunik/certificate", - "version": "v1.1.3", + "name": "lcobucci/jwt", + "version": "5.6.0", "source": { "type": "git", - "url": "https://github.com/kelunik/certificate.git", - "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e" + "url": "https://github.com/lcobucci/jwt.git", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e", - "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/bb3e9f21e4196e8afc41def81ef649c164bca25e", + "reference": "bb3e9f21e4196e8afc41def81ef649c164bca25e", "shasum": "" }, "require": { "ext-openssl": "*", - "php": ">=7.0" + "ext-sodium": "*", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "psr/clock": "^1.0" }, "require-dev": { - "amphp/php-cs-fixer-config": "^2", - "phpunit/phpunit": "^6 | 7 | ^8 | ^9" + "infection/infection": "^0.29", + "lcobucci/clock": "^3.2", + "lcobucci/coding-standard": "^11.0", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.10.7", + "phpstan/phpstan-deprecation-rules": "^1.1.3", + "phpstan/phpstan-phpunit": "^1.3.10", + "phpstan/phpstan-strict-rules": "^1.5.0", + "phpunit/phpunit": "^11.1" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } + "suggest": { + "lcobucci/clock": ">= 3.2" }, + "type": "library", "autoload": { "psr-4": { - "Kelunik\\Certificate\\": "src" + "Lcobucci\\JWT\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" } ], - "description": "Access certificate details and transform between different formats.", + "description": "A simple library to work with JSON Web Token and JSON Web Signature", "keywords": [ - "DER", - "certificate", - "certificates", - "openssl", - "pem", - "x509" + "JWS", + "jwt" ], "support": { - "issues": "https://github.com/kelunik/certificate/issues", - "source": "https://github.com/kelunik/certificate/tree/v1.1.3" + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/5.6.0" }, - "time": "2023-02-03T21:26:53+00:00" + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2025-10-17T11:30:53+00:00" }, { - "name": "laravel/fortify", - "version": "v1.27.0", + "name": "league/commonmark", + "version": "2.8.2", "source": { "type": "git", - "url": "https://github.com/laravel/fortify.git", - "reference": "0fb2ec99dfee77ed66884668fc06683acca91ebd" + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "59fb075d2101740c337c7216e3f32b36c204218b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/fortify/zipball/0fb2ec99dfee77ed66884668fc06683acca91ebd", - "reference": "0fb2ec99dfee77ed66884668fc06683acca91ebd", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b", + "reference": "59fb075d2101740c337c7216e3f32b36c204218b", "shasum": "" }, "require": { - "bacon/bacon-qr-code": "^3.0", - "ext-json": "*", - "illuminate/support": "^10.0|^11.0|^12.0", - "php": "^8.1", - "pragmarx/google2fa": "^8.0", - "symfony/console": "^6.0|^7.0" + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { - "mockery/mockery": "^1.0", - "orchestra/testbench": "^8.16|^9.0|^10.0", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^10.4|^11.3" + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0 || ^8.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" }, "type": "library", "extra": { - "laravel": { - "providers": [ - "Laravel\\Fortify\\FortifyServiceProvider" - ] - }, "branch-alias": { - "dev-master": "1.x-dev" + "dev-main": "2.9-dev" } }, "autoload": { "psr-4": { - "Laravel\\Fortify\\": "src/" + "League\\CommonMark\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" } ], - "description": "Backend controllers and scaffolding for Laravel authentication.", + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", "keywords": [ - "auth", - "laravel" + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" ], "support": { - "issues": "https://github.com/laravel/fortify/issues", - "source": "https://github.com/laravel/fortify" + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" }, - "time": "2025-06-11T14:30:52+00:00" + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2026-03-19T13:16:38+00:00" }, { - "name": "laravel/framework", - "version": "v11.54.0", + "name": "league/config", + "version": "v1.2.0", "source": { "type": "git", - "url": "https://github.com/laravel/framework.git", - "reference": "4e7ae67eedd803eaea8ceb5f7e113f495d2c0c58" + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/4e7ae67eedd803eaea8ceb5f7e113f495d2c0c58", - "reference": "4e7ae67eedd803eaea8ceb5f7e113f495d2c0c58", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", "shasum": "" }, "require": { - "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12|^0.13|^0.14", - "composer-runtime-api": "^2.2", - "doctrine/inflector": "^2.0.5", - "dragonmantank/cron-expression": "^3.4", - "egulias/email-validator": "^3.2.1|^4.0", - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "ext-mbstring": "*", - "ext-openssl": "*", - "ext-session": "*", - "ext-tokenizer": "*", - "fruitcake/php-cors": "^1.3", - "guzzlehttp/guzzle": "^7.8.2", - "guzzlehttp/uri-template": "^1.0", - "laravel/prompts": "^0.1.18|^0.2.0|^0.3.0", - "laravel/serializable-closure": "^1.3|^2.0", - "league/commonmark": "^2.7", - "league/flysystem": "^3.25.1", - "league/flysystem-local": "^3.25.1", - "league/uri": "^7.5.1", - "monolog/monolog": "^3.0", - "nesbot/carbon": "^2.72.6|^3.8.4", - "nunomaduro/termwind": "^2.0", - "php": "^8.2", - "psr/container": "^1.1.1|^2.0.1", - "psr/log": "^1.0|^2.0|^3.0", - "psr/simple-cache": "^1.0|^2.0|^3.0", - "ramsey/uuid": "^4.7", - "symfony/console": "^7.0.3", - "symfony/error-handler": "^7.0.3", - "symfony/finder": "^7.0.3", - "symfony/http-foundation": "^7.2.0", - "symfony/http-kernel": "^7.0.3", - "symfony/mailer": "^7.0.3", - "symfony/mime": "^7.0.3", - "symfony/polyfill-php83": "^1.31", - "symfony/process": "^7.0.3", - "symfony/routing": "^7.0.3", - "symfony/uid": "^7.0.3", - "symfony/var-dumper": "^7.0.3", - "tijsverkoyen/css-to-inline-styles": "^2.2.5", - "vlucas/phpdotenv": "^5.6.1", - "voku/portable-ascii": "^2.0.2" - }, - "conflict": { - "tightenco/collect": "<5.5.33" - }, - "provide": { - "psr/container-implementation": "1.1|2.0", - "psr/log-implementation": "1.0|2.0|3.0", - "psr/simple-cache-implementation": "1.0|2.0|3.0" - }, - "replace": { - "illuminate/auth": "self.version", - "illuminate/broadcasting": "self.version", - "illuminate/bus": "self.version", - "illuminate/cache": "self.version", - "illuminate/collections": "self.version", - "illuminate/concurrency": "self.version", - "illuminate/conditionable": "self.version", - "illuminate/config": "self.version", - "illuminate/console": "self.version", - "illuminate/container": "self.version", - "illuminate/contracts": "self.version", - "illuminate/cookie": "self.version", - "illuminate/database": "self.version", - "illuminate/encryption": "self.version", - "illuminate/events": "self.version", - "illuminate/filesystem": "self.version", - "illuminate/hashing": "self.version", - "illuminate/http": "self.version", - "illuminate/log": "self.version", - "illuminate/macroable": "self.version", - "illuminate/mail": "self.version", - "illuminate/notifications": "self.version", - "illuminate/pagination": "self.version", - "illuminate/pipeline": "self.version", - "illuminate/process": "self.version", - "illuminate/queue": "self.version", - "illuminate/redis": "self.version", - "illuminate/routing": "self.version", - "illuminate/session": "self.version", - "illuminate/support": "self.version", - "illuminate/testing": "self.version", - "illuminate/translation": "self.version", - "illuminate/validation": "self.version", - "illuminate/view": "self.version", - "spatie/once": "*" - }, - "require-dev": { - "ably/ably-php": "^1.0", - "aws/aws-sdk-php": "^3.322.9", - "ext-gmp": "*", - "fakerphp/faker": "^1.24", - "guzzlehttp/promises": "^2.0.3", - "guzzlehttp/psr7": "^2.4", - "laravel/pint": "^1.18", - "league/flysystem-aws-s3-v3": "^3.25.1", - "league/flysystem-ftp": "^3.25.1", - "league/flysystem-path-prefixing": "^3.25.1", - "league/flysystem-read-only": "^3.25.1", - "league/flysystem-sftp-v3": "^3.25.1", - "mockery/mockery": "^1.6.10", - "orchestra/testbench-core": "^9.18.0", - "pda/pheanstalk": "^5.0.6", - "php-http/discovery": "^1.15", - "phpstan/phpstan": "2.1.41", - "phpunit/phpunit": "^10.5.35|^11.3.6|^12.0.1", - "predis/predis": "^2.3", - "resend/resend-php": "^0.10.0", - "symfony/cache": "^7.0.3", - "symfony/http-client": "^7.0.3", - "symfony/psr-http-message-bridge": "^7.0.3", - "symfony/translation": "^7.0.3" + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" }, - "suggest": { - "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", - "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", - "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", - "ext-apcu": "Required to use the APC cache driver.", - "ext-fileinfo": "Required to use the Filesystem class.", - "ext-ftp": "Required to use the Flysystem FTP driver.", - "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", - "ext-memcached": "Required to use the memcache cache driver.", - "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", - "ext-pdo": "Required to use all database features.", - "ext-posix": "Required to use all features of the queue worker.", - "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", - "filp/whoops": "Required for friendly error pages in development (^2.14.3).", - "laravel/tinker": "Required to use the tinker console command (^2.0).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", - "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", - "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", - "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", - "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", - "mockery/mockery": "Required to use mocking (^1.6).", - "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", - "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", - "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.3.6|^12.0.1).", - "predis/predis": "Required to use the predis connector (^2.3).", - "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", - "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^7.0).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", - "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", - "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", - "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "11.x-dev" + "dev-main": "1.2-dev" } }, "autoload": { - "files": [ - "src/Illuminate/Collections/functions.php", - "src/Illuminate/Collections/helpers.php", - "src/Illuminate/Events/functions.php", - "src/Illuminate/Filesystem/functions.php", - "src/Illuminate/Foundation/helpers.php", - "src/Illuminate/Log/functions.php", - "src/Illuminate/Support/functions.php", - "src/Illuminate/Support/helpers.php" - ], "psr-4": { - "Illuminate\\": "src/Illuminate/", - "Illuminate\\Support\\": [ - "src/Illuminate/Macroable/", - "src/Illuminate/Collections/", - "src/Illuminate/Conditionable/" - ] + "League\\Config\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" } ], - "description": "The Laravel Framework.", - "homepage": "https://laravel.com", + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", "keywords": [ - "framework", - "laravel" + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" ], "support": { - "issues": "https://github.com/laravel/framework/issues", - "source": "https://github.com/laravel/framework" + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" }, - "time": "2026-05-26T23:41:51+00:00" + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" }, { - "name": "laravel/helpers", - "version": "v1.7.2", + "name": "league/flysystem", + "version": "3.34.0", "source": { "type": "git", - "url": "https://github.com/laravel/helpers.git", - "reference": "672d79d5b5f65dc821e57783fa11f22c4d762d70" + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/helpers/zipball/672d79d5b5f65dc821e57783fa11f22c4d762d70", - "reference": "672d79d5b5f65dc821e57783fa11f22c4d762d70", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", + "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", "shasum": "" }, "require": { - "illuminate/support": "~5.8.0|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "php": "^7.2.0|^8.0" + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" }, "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3|^2", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2|^2", + "phpseclib/phpseclib": "^3.0.36", "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^7.0|^8.0|^9.0|^10.0" + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, "autoload": { - "files": [ - "src/helpers.php" - ] + "psr-4": { + "League\\Flysystem\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2435,81 +2569,106 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Dries Vints", - "email": "dries@laravel.com" + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" } ], - "description": "Provides backwards compatibility for helpers in the latest Laravel release.", + "description": "File storage abstraction for PHP", "keywords": [ - "helpers", - "laravel" + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" ], "support": { - "source": "https://github.com/laravel/helpers/tree/v1.7.2" + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.34.0" }, - "time": "2025-01-24T15:41:25+00:00" + "time": "2026-05-14T10:28:08+00:00" }, { - "name": "laravel/horizon", - "version": "v5.48.2", + "name": "league/flysystem-local", + "version": "3.31.0", "source": { "type": "git", - "url": "https://github.com/laravel/horizon.git", - "reference": "2ebe3cb25ab6461b53a4e3ef42e167edeafe7932" + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/horizon/zipball/2ebe3cb25ab6461b53a4e3ef42e167edeafe7932", - "reference": "2ebe3cb25ab6461b53a4e3ef42e167edeafe7932", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079", "shasum": "" }, "require": { - "ext-json": "*", - "ext-pcntl": "*", - "ext-posix": "*", - "illuminate/contracts": "^9.21|^10.0|^11.0|^12.0|^13.0", - "illuminate/queue": "^9.21|^10.0|^11.0|^12.0|^13.0", - "illuminate/support": "^9.21|^10.0|^11.0|^12.0|^13.0", - "laravel/sentinel": "^1.0", - "nesbot/carbon": "^2.17|^3.0", - "php": "^8.0", - "ramsey/uuid": "^4.0", - "symfony/console": "^6.0|^7.0|^8.0", - "symfony/error-handler": "^6.0|^7.0|^8.0", - "symfony/polyfill-php83": "^1.28", - "symfony/process": "^6.0|^7.0|^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "orchestra/testbench": "^7.56|^8.37|^9.16|^10.9|^11.0", - "phpstan/phpstan": "^1.10|^2.0", - "predis/predis": "^1.1|^2.0|^3.0" - }, - "suggest": { - "ext-redis": "Required to use the Redis PHP driver.", - "predis/predis": "Required when not using the Redis PHP driver (^1.1|^2.0|^3.0)." + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" }, "type": "library", - "extra": { - "laravel": { - "aliases": { - "Horizon": "Laravel\\Horizon\\Horizon" - }, - "providers": [ - "Laravel\\Horizon\\HorizonServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "6.x-dev" + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0" + }, + "time": "2026-01-23T15:30:45+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" }, + "type": "library", "autoload": { "psr-4": { - "Laravel\\Horizon\\": "src/" + "League\\MimeTypeDetection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2518,120 +2677,148 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" } ], - "description": "Dashboard and code-driven configuration for Laravel queues.", - "keywords": [ - "laravel", - "queue" - ], + "description": "Mime-type detection for Flysystem", "support": { - "issues": "https://github.com/laravel/horizon/issues", - "source": "https://github.com/laravel/horizon/tree/v5.48.2" + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" }, - "time": "2026-07-27T13:13:49+00:00" + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-09-21T08:32:55+00:00" }, { - "name": "laravel/prompts", - "version": "v0.3.18", + "name": "league/oauth1-client", + "version": "v1.11.0", "source": { "type": "git", - "url": "https://github.com/laravel/prompts.git", - "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72" + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "f9c94b088837eb1aae1ad7c4f23eb65cc6993055" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/a19af51bb144bf87f08397921fa619f85c7d4e72", - "reference": "a19af51bb144bf87f08397921fa619f85c7d4e72", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/f9c94b088837eb1aae1ad7c4f23eb65cc6993055", + "reference": "f9c94b088837eb1aae1ad7c4f23eb65cc6993055", "shasum": "" }, "require": { - "composer-runtime-api": "^2.2", - "ext-mbstring": "*", - "php": "^8.1", - "symfony/console": "^6.2|^7.0|^8.0" - }, - "conflict": { - "illuminate/console": ">=10.17.0 <10.25.0", - "laravel/framework": ">=10.17.0 <10.25.0" + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "guzzlehttp/psr7": "^1.7|^2.0", + "php": ">=7.1||>=8.0" }, "require-dev": { - "illuminate/collections": "^10.0|^11.0|^12.0|^13.0", - "mockery/mockery": "^1.5", - "pestphp/pest": "^2.3|^3.4|^4.0", - "phpstan/phpstan": "^1.12.28", - "phpstan/phpstan-mockery": "^1.1.3" + "ext-simplexml": "*", + "friendsofphp/php-cs-fixer": "^2.17", + "mockery/mockery": "^1.3.3", + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5||9.5" }, "suggest": { - "ext-pcntl": "Required for the spinner to be animated." + "ext-simplexml": "For decoding XML-based responses." }, "type": "library", "extra": { "branch-alias": { - "dev-main": "0.3.x-dev" + "dev-master": "1.0-dev", + "dev-develop": "2.0-dev" } }, "autoload": { - "files": [ - "src/helpers.php" - ], "psr-4": { - "Laravel\\Prompts\\": "src/" + "League\\OAuth1\\Client\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Add beautiful and user-friendly forms to your command-line applications.", + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], "support": { - "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.3.18" + "issues": "https://github.com/thephpleague/oauth1-client/issues", + "source": "https://github.com/thephpleague/oauth1-client/tree/v1.11.0" }, - "time": "2026-05-19T00:47:18+00:00" + "time": "2024-12-10T19:59:05+00:00" }, { - "name": "laravel/sanctum", - "version": "v4.1.1", + "name": "league/uri", + "version": "7.8.1", "source": { "type": "git", - "url": "https://github.com/laravel/sanctum.git", - "reference": "a360a6a1fd2400ead4eb9b6a9c1bb272939194f5" + "url": "https://github.com/thephpleague/uri.git", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sanctum/zipball/a360a6a1fd2400ead4eb9b6a9c1bb272939194f5", - "reference": "a360a6a1fd2400ead4eb9b6a9c1bb272939194f5", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4", + "reference": "08cf38e3924d4f56238125547b5720496fac8fd4", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/console": "^11.0|^12.0", - "illuminate/contracts": "^11.0|^12.0", - "illuminate/database": "^11.0|^12.0", - "illuminate/support": "^11.0|^12.0", - "php": "^8.2", - "symfony/console": "^7.0" + "league/uri-interfaces": "^7.8.1", + "php": "^8.1", + "psr/http-factory": "^1" }, - "require-dev": { - "mockery/mockery": "^1.6", - "orchestra/testbench": "^9.0|^10.0", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^11.3" + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", "extra": { - "laravel": { - "providers": [ - "Laravel\\Sanctum\\SanctumServiceProvider" - ] + "branch-alias": { + "dev-master": "7.x-dev" } }, "autoload": { "psr-4": { - "Laravel\\Sanctum\\": "src/" + "League\\Uri\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -2640,57 +2827,87 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" } ], - "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", "keywords": [ - "auth", - "laravel", - "sanctum" + "URN", + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc2141", + "rfc3986", + "rfc3987", + "rfc6570", + "rfc8141", + "uri", + "uri-template", + "url", + "ws" ], "support": { - "issues": "https://github.com/laravel/sanctum/issues", - "source": "https://github.com/laravel/sanctum" + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.8.1" }, - "time": "2025-04-23T13:03:38+00:00" + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-15T20:22:25+00:00" }, { - "name": "laravel/sentinel", - "version": "v1.1.0", + "name": "league/uri-interfaces", + "version": "7.8.1", "source": { "type": "git", - "url": "https://github.com/laravel/sentinel.git", - "reference": "972d9885d9d14312a118e9565c4e6ecc5e751ea1" + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sentinel/zipball/972d9885d9d14312a118e9565c4e6ecc5e751ea1", - "reference": "972d9885d9d14312a118e9565c4e6ecc5e751ea1", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928", + "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/container": "^8.37|^9.0|^10.0|^11.0|^12.0|^13.0", - "php": "^8.0" + "ext-filter": "*", + "php": "^8.1", + "psr/http-message": "^1.1 || ^2.0" }, - "require-dev": { - "laravel/pint": "^1.27", - "orchestra/testbench": "^6.47.1|^7.56|^8.37|^9.16|^10.9|^11.0", - "phpstan/phpstan": "^2.1.33" + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", "extra": { - "laravel": { - "providers": [ - "Laravel\\Sentinel\\SentinelServiceProvider" - ] + "branch-alias": { + "dev-master": "7.x-dev" } }, "autoload": { "psr-4": { - "Laravel\\Sentinel\\": "src/" + "League\\Uri\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -2699,52 +2916,71 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Mior Muhammad Zaki", - "email": "mior@laravel.com" + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" } ], + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], "support": { - "source": "https://github.com/laravel/sentinel/tree/v1.1.0" + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1" }, - "time": "2026-03-24T14:03:38+00:00" + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2026-03-08T20:05:35+00:00" }, { - "name": "laravel/serializable-closure", - "version": "v2.0.13", + "name": "mlocati/ip-lib", + "version": "1.22.0", "source": { "type": "git", - "url": "https://github.com/laravel/serializable-closure.git", - "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce" + "url": "https://github.com/mlocati/ip-lib.git", + "reference": "4e40ffd3bf9989db19403d89c4d8be44b87b8a91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b566ee0dd251f3c4078bed003a7ce015f5ea6dce", - "reference": "b566ee0dd251f3c4078bed003a7ce015f5ea6dce", + "url": "https://api.github.com/repos/mlocati/ip-lib/zipball/4e40ffd3bf9989db19403d89c4d8be44b87b8a91", + "reference": "4e40ffd3bf9989db19403d89c4d8be44b87b8a91", "shasum": "" }, "require": { - "php": "^8.1" + "php": ">=5.3.3" }, "require-dev": { - "illuminate/support": "^10.0|^11.0|^12.0|^13.0", - "nesbot/carbon": "^2.67|^3.0", - "pestphp/pest": "^2.36|^3.0|^4.0", - "phpstan/phpstan": "^2.0", - "symfony/var-dumper": "^6.2.0|^7.0.0|^8.0.0" + "ext-pdo_sqlite": "*", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.5 || ^9.5" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.x-dev" - } - }, "autoload": { "psr-4": { - "Laravel\\SerializableClosure\\": "src/" + "IPLib\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2753,67 +2989,111 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Nuno Maduro", - "email": "nuno@laravel.com" + "name": "Michele Locati", + "email": "mlocati@gmail.com", + "homepage": "https://github.com/mlocati", + "role": "Author" } ], - "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "description": "Handle IPv4, IPv6 addresses and ranges", + "homepage": "https://github.com/mlocati/ip-lib", "keywords": [ - "closure", - "laravel", - "serializable" + "IP", + "address", + "addresses", + "ipv4", + "ipv6", + "manage", + "managing", + "matching", + "network", + "networking", + "range", + "subnet" ], "support": { - "issues": "https://github.com/laravel/serializable-closure/issues", - "source": "https://github.com/laravel/serializable-closure" + "issues": "https://github.com/mlocati/ip-lib/issues", + "source": "https://github.com/mlocati/ip-lib/tree/1.22.0" }, - "time": "2026-04-16T14:03:50+00:00" + "funding": [ + { + "url": "https://github.com/sponsors/mlocati", + "type": "github" + }, + { + "url": "https://paypal.me/mlocati", + "type": "other" + } + ], + "time": "2025-10-15T12:35:09+00:00" }, { - "name": "laravel/tinker", - "version": "v2.10.1", + "name": "monolog/monolog", + "version": "3.10.0", "source": { "type": "git", - "url": "https://github.com/laravel/tinker.git", - "reference": "22177cc71807d38f2810c6204d8f7183d88a57d3" + "url": "https://github.com/Seldaek/monolog.git", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/22177cc71807d38f2810c6204d8f7183d88a57d3", - "reference": "22177cc71807d38f2810c6204d8f7183d88a57d3", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", "shasum": "" }, "require": { - "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", - "php": "^7.2.5|^8.0", - "psy/psysh": "^0.11.1|^0.12.0", - "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" }, "require-dev": { - "mockery/mockery": "~1.3.3|^1.4.2", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.5.8|^9.3.3|^10.0" + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8 || ^2.0", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" }, "suggest": { - "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0)." + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" }, "type": "library", "extra": { - "laravel": { - "providers": [ - "Laravel\\Tinker\\TinkerServiceProvider" - ] + "branch-alias": { + "dev-main": "3.x-dev" } }, "autoload": { "psr-4": { - "Laravel\\Tinker\\": "src/" + "Monolog\\": "src/Monolog" } }, "notification-url": "https://packagist.org/downloads/", @@ -2822,392 +3102,401 @@ ], "authors": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" } ], - "description": "Powerful REPL for the Laravel framework.", + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", "keywords": [ - "REPL", - "Tinker", - "laravel", - "psysh" + "log", + "logging", + "psr-3" ], "support": { - "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.10.1" + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.10.0" }, - "time": "2025-01-27T14:24:01+00:00" + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2026-01-02T08:56:05+00:00" }, { - "name": "lcobucci/jwt", - "version": "5.5.0", + "name": "nesbot/carbon", + "version": "3.11.4", "source": { "type": "git", - "url": "https://github.com/lcobucci/jwt.git", - "reference": "a835af59b030d3f2967725697cf88300f579088e" + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/a835af59b030d3f2967725697cf88300f579088e", - "reference": "a835af59b030d3f2967725697cf88300f579088e", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", + "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", "shasum": "" }, "require": { - "ext-openssl": "*", - "ext-sodium": "*", - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "psr/clock": "^1.0" + "carbonphp/carbon-doctrine-types": "<100.0", + "ext-json": "*", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3.12 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0" }, - "require-dev": { - "infection/infection": "^0.29", - "lcobucci/clock": "^3.2", - "lcobucci/coding-standard": "^11.0", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.2", - "phpstan/phpstan": "^1.10.7", - "phpstan/phpstan-deprecation-rules": "^1.1.3", - "phpstan/phpstan-phpunit": "^1.3.10", - "phpstan/phpstan-strict-rules": "^1.5.0", - "phpunit/phpunit": "^11.1" + "provide": { + "psr/clock-implementation": "1.0" }, - "suggest": { - "lcobucci/clock": ">= 3.2" + "require-dev": { + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^v3.87.1", + "kylekatarnls/multi-tester": "^2.5.3", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.22", + "phpunit/phpunit": "^10.5.53", + "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0" }, + "bin": [ + "bin/carbon" + ], "type": "library", + "extra": { + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" + } + }, "autoload": { "psr-4": { - "Lcobucci\\JWT\\": "src" + "Carbon\\": "src/Carbon/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Luís Cobucci", - "email": "lcobucci@gmail.com", - "role": "Developer" + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" } ], - "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbonphp.github.io/carbon/", "keywords": [ - "JWS", - "jwt" + "date", + "datetime", + "time" ], "support": { - "issues": "https://github.com/lcobucci/jwt/issues", - "source": "https://github.com/lcobucci/jwt/tree/5.5.0" + "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html", + "issues": "https://github.com/CarbonPHP/carbon/issues", + "source": "https://github.com/CarbonPHP/carbon" }, "funding": [ { - "url": "https://github.com/lcobucci", + "url": "https://github.com/sponsors/kylekatarnls", "type": "github" }, { - "url": "https://www.patreon.com/lcobucci", - "type": "patreon" + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" } ], - "time": "2025-01-26T21:29:45+00:00" + "time": "2026-04-07T09:57:54+00:00" }, { - "name": "league/commonmark", - "version": "2.8.2", + "name": "nette/schema", + "version": "v1.3.5", "source": { "type": "git", - "url": "https://github.com/thephpleague/commonmark.git", - "reference": "59fb075d2101740c337c7216e3f32b36c204218b" + "url": "https://github.com/nette/schema.git", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b", - "reference": "59fb075d2101740c337c7216e3f32b36c204218b", + "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", + "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", "shasum": "" }, "require": { - "ext-mbstring": "*", - "league/config": "^1.1.1", - "php": "^7.4 || ^8.0", - "psr/event-dispatcher": "^1.0", - "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "cebe/markdown": "^1.0", - "commonmark/cmark": "0.31.1", - "commonmark/commonmark.js": "0.31.1", - "composer/package-versions-deprecated": "^1.8", - "embed/embed": "^4.4", - "erusev/parsedown": "^1.0", - "ext-json": "*", - "github/gfm": "0.29.0", - "michelf/php-markdown": "^1.4 || ^2.0", - "nyholm/psr7": "^1.5", - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", - "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0 | ^7.0 || ^8.0", - "symfony/process": "^5.4 | ^6.0 | ^7.0 || ^8.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0 || ^8.0", - "unleashedtech/php-coding-standard": "^3.1.1", - "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" + "nette/utils": "^4.0", + "php": "8.1 - 8.5" }, - "suggest": { - "symfony/yaml": "v2.3+ required if using the Front Matter extension" + "require-dev": { + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.6", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1.39@stable", + "tracy/tracy": "^2.8" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.9-dev" + "dev-master": "1.3-dev" } }, "autoload": { "psr-4": { - "League\\CommonMark\\": "src" - } + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" } ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", - "homepage": "https://commonmark.thephpleague.com", + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", "keywords": [ - "commonmark", - "flavored", - "gfm", - "github", - "github-flavored", - "markdown", - "md", - "parser" + "config", + "nette" ], "support": { - "docs": "https://commonmark.thephpleague.com/", - "forum": "https://github.com/thephpleague/commonmark/discussions", - "issues": "https://github.com/thephpleague/commonmark/issues", - "rss": "https://github.com/thephpleague/commonmark/releases.atom", - "source": "https://github.com/thephpleague/commonmark" + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.5" }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/commonmark", - "type": "tidelift" - } - ], - "time": "2026-03-19T13:16:38+00:00" + "time": "2026-02-23T03:47:12+00:00" }, { - "name": "league/config", - "version": "v1.2.0", + "name": "nette/utils", + "version": "v4.1.4", "source": { "type": "git", - "url": "https://github.com/thephpleague/config.git", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + "url": "https://github.com/nette/utils.git", + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", - "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "url": "https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7", + "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7", "shasum": "" }, "require": { - "dflydev/dot-access-data": "^3.0.1", - "nette/schema": "^1.2", - "php": "^7.4 || ^8.0" + "php": "8.2 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" }, "require-dev": { - "phpstan/phpstan": "^1.8.2", - "phpunit/phpunit": "^9.5.5", - "scrutinizer/ocular": "^1.8.1", - "unleashedtech/php-coding-standard": "^3.1", - "vimeo/psalm": "^4.7.3" + "jetbrains/phpstorm-attributes": "^1.2", + "nette/phpstan-rules": "^1.0", + "nette/tester": "^2.5", + "phpstan/extension-installer": "^1.4@stable", + "phpstan/phpstan": "^2.1@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.2-dev" + "dev-master": "4.1-dev" } }, "autoload": { "psr-4": { - "League\\Config\\": "src" - } + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" ], "authors": [ { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "https://www.colinodell.com", - "role": "Lead Developer" + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" } ], - "description": "Define configuration arrays with strict schemas and access values with dot notation", - "homepage": "https://config.thephpleague.com", + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", "keywords": [ "array", - "config", - "configuration", - "dot", - "dot-access", - "nested", - "schema" + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" ], "support": { - "docs": "https://config.thephpleague.com/", - "issues": "https://github.com/thephpleague/config/issues", - "rss": "https://github.com/thephpleague/config/releases.atom", - "source": "https://github.com/thephpleague/config" + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.1.4" }, - "funding": [ - { - "url": "https://www.colinodell.com/sponsor", - "type": "custom" - }, - { - "url": "https://www.paypal.me/colinpodell/10.00", - "type": "custom" - }, - { - "url": "https://github.com/colinodell", - "type": "github" - } - ], - "time": "2022-12-11T20:36:23+00:00" + "time": "2026-05-11T20:49:54+00:00" }, { - "name": "league/flysystem", - "version": "3.34.0", + "name": "nikic/php-parser", + "version": "v5.7.0", "source": { "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", - "reference": "2daaac3b0d4c83ea7ed5d8586e786f5d00f3540e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { - "league/flysystem-local": "^3.0.0", - "league/mime-type-detection": "^1.0.0", - "php": "^8.0.2" - }, - "conflict": { - "async-aws/core": "<1.19.0", - "async-aws/s3": "<1.14.0", - "aws/aws-sdk-php": "3.209.31 || 3.210.0", - "guzzlehttp/guzzle": "<7.0", - "guzzlehttp/ringphp": "<1.1.1", - "phpseclib/phpseclib": "3.0.15", - "symfony/http-client": "<5.2" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "async-aws/s3": "^1.5 || ^2.0", - "async-aws/simple-s3": "^1.1 || ^2.0", - "aws/aws-sdk-php": "^3.295.10", - "composer/semver": "^3.0", - "ext-fileinfo": "*", - "ext-ftp": "*", - "ext-mongodb": "^1.3|^2", - "ext-zip": "*", - "friendsofphp/php-cs-fixer": "^3.5", - "google/cloud-storage": "^1.23", - "guzzlehttp/psr7": "^2.6", - "microsoft/azure-storage-blob": "^1.1", - "mongodb/mongodb": "^1.2|^2", - "phpseclib/phpseclib": "^3.0.36", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5.11|^10.0", - "sabre/dav": "^4.6.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, "autoload": { "psr-4": { - "League\\Flysystem\\": "src" + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" + "name": "Nikita Popov" } ], - "description": "File storage abstraction for PHP", + "description": "A PHP parser written in PHP", "keywords": [ - "WebDAV", - "aws", - "cloud", - "file", - "files", - "filesystem", - "filesystems", - "ftp", - "s3", - "sftp", - "storage" + "parser", + "php" ], "support": { - "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.34.0" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2026-05-14T10:28:08+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { - "name": "league/flysystem-local", - "version": "3.31.0", + "name": "nunomaduro/termwind", + "version": "v2.4.0", "source": { "type": "git", - "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079" + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "712a31b768f5daea284c2169a7d227031001b9a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079", - "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/712a31b768f5daea284c2169a7d227031001b9a8", + "reference": "712a31b768f5daea284c2169a7d227031001b9a8", "shasum": "" }, "require": { - "ext-fileinfo": "*", - "league/flysystem": "^3.0.0", - "league/mime-type-detection": "^1.0.0", - "php": "^8.0.2" + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.4.4 || ^8.0.4" + }, + "require-dev": { + "illuminate/console": "^11.47.0", + "laravel/pint": "^1.27.1", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.3.2", + "phpstan/phpstan": "^1.12.32", + "phpstan/phpstan-strict-rules": "^1.6.2", + "symfony/var-dumper": "^7.3.5 || ^8.0.4", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" }, "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, "autoload": { + "files": [ + "src/Functions.php" + ], "psr-4": { - "League\\Flysystem\\Local\\": "" + "Termwind\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -3216,65 +3505,66 @@ ], "authors": [ { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" } ], - "description": "Local filesystem adapter for Flysystem.", + "description": "It's like Tailwind CSS, but for the console.", "keywords": [ - "Flysystem", - "file", - "files", - "filesystem", - "local" + "cli", + "console", + "css", + "package", + "php", + "style" ], "support": { - "source": "https://github.com/thephpleague/flysystem-local/tree/3.31.0" + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.4.0" }, - "time": "2026-01-23T15:30:45+00:00" + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2026-02-16T23:10:27+00:00" }, { - "name": "league/fractal", - "version": "0.20.2", + "name": "paragonie/constant_time_encoding", + "version": "v3.1.3", "source": { "type": "git", - "url": "https://github.com/thephpleague/fractal.git", - "reference": "573ca2e0e348a7fe573a3e8fbc29a6588ece8c4e" + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/fractal/zipball/573ca2e0e348a7fe573a3e8fbc29a6588ece8c4e", - "reference": "573ca2e0e348a7fe573a3e8fbc29a6588ece8c4e", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", "shasum": "" }, "require": { - "php": ">=7.4" + "php": "^8" }, "require-dev": { - "doctrine/orm": "^2.5", - "illuminate/contracts": "~5.0", - "laminas/laminas-paginator": "~2.12", - "mockery/mockery": "^1.3", - "pagerfanta/pagerfanta": "~1.0.0|~4.0.0", - "phpstan/phpstan": "^1.4", - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "~3.4", - "vimeo/psalm": "^4.30" - }, - "suggest": { - "illuminate/pagination": "The Illuminate Pagination component.", - "laminas/laminas-paginator": "Laminas Framework Paginator", - "pagerfanta/pagerfanta": "Pagerfanta Paginator" + "infection/infection": "^0", + "nikic/php-fuzzer": "^0", + "phpunit/phpunit": "^9|^10|^11", + "vimeo/psalm": "^4|^5|^6" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.20.x-dev" - } - }, "autoload": { "psr-4": { - "League\\Fractal\\": "src" + "ParagonIE\\ConstantTime\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -3283,127 +3573,116 @@ ], "authors": [ { - "name": "Phil Sturgeon", - "email": "me@philsturgeon.uk", - "homepage": "http://philsturgeon.uk/", - "role": "Developer" + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" } ], - "description": "Handle the output of complex data structures ready for API output.", - "homepage": "http://fractal.thephpleague.com/", + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", "keywords": [ - "api", - "json", - "league", - "rest" + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" ], "support": { - "issues": "https://github.com/thephpleague/fractal/issues", - "source": "https://github.com/thephpleague/fractal/tree/0.20.2" + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" }, - "time": "2025-02-14T21:33:14+00:00" + "time": "2025-09-24T15:06:41+00:00" }, { - "name": "league/mime-type-detection", - "version": "1.16.0", + "name": "paragonie/random_compat", + "version": "v9.99.100", "source": { "type": "git", - "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", - "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", "shasum": "" }, "require": { - "ext-fileinfo": "*", - "php": "^7.4 || ^8.0" + "php": ">= 7" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" }, - "type": "library", - "autoload": { - "psr-4": { - "League\\MimeTypeDetection\\": "src" - } + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." }, + "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Frank de Jonge", - "email": "info@frankdejonge.nl" + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" } ], - "description": "Mime-type detection for Flysystem", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], "support": { - "issues": "https://github.com/thephpleague/mime-type-detection/issues", - "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" }, - "funding": [ - { - "url": "https://github.com/frankdejonge", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/league/flysystem", - "type": "tidelift" - } - ], - "time": "2024-09-21T08:32:55+00:00" + "time": "2020-10-15T08:29:30+00:00" }, { - "name": "league/uri", - "version": "7.8.1", + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/thephpleague/uri.git", - "reference": "08cf38e3924d4f56238125547b5720496fac8fd4" + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/08cf38e3924d4f56238125547b5720496fac8fd4", - "reference": "08cf38e3924d4f56238125547b5720496fac8fd4", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", "shasum": "" }, "require": { - "league/uri-interfaces": "^7.8.1", - "php": "^8.1", - "psr/http-factory": "^1" - }, - "conflict": { - "league/uri-schemes": "^1.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-dom": "to convert the URI into an HTML anchor tag", - "ext-fileinfo": "to create Data URI from file contennts", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "ext-uri": "to use the PHP native URI class", - "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", - "league/uri-components": "to provide additional tools to manipulate URI objects components", - "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", - "php-64bit": "to improve IPV4 host parsing", - "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "7.x-dev" + "dev-2.x": "2.x-dev" } }, "autoload": { "psr-4": { - "League\\Uri\\": "" + "phpDocumentor\\Reflection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -3412,87 +3691,67 @@ ], "authors": [ { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" - } - ], - "description": "URI manipulation library", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "URN", - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "middleware", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc2141", - "rfc3986", - "rfc3987", - "rfc6570", - "rfc8141", - "uri", - "uri-template", - "url", - "ws" - ], - "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.8.1" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" } ], - "time": "2026-03-15T20:22:25+00:00" + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" }, { - "name": "league/uri-interfaces", - "version": "7.8.1", + "name": "phpdocumentor/reflection-docblock", + "version": "6.0.3", "source": { "type": "git", - "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928" + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/85d5c77c5d6d3af6c54db4a78246364908f3c928", - "reference": "85d5c77c5d6d3af6c54db4a78246364908f3c928", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.1", "ext-filter": "*", - "php": "^8.1", - "psr/http-message": "^1.1 || ^2.0" + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^2.0", + "phpstan/phpdoc-parser": "^2.0", + "webmozart/assert": "^1.9.1 || ^2" }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-gmp": "to improve IPV4 host parsing", - "ext-intl": "to handle IDN host with the best performance", - "php-64bit": "to improve IPV4 host parsing", - "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", - "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + "require-dev": { + "mockery/mockery": "~1.3.5 || ~1.6.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^5.26", + "shipmonk/dead-code-detector": "^0.5.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "7.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { "psr-4": { - "League\\Uri\\": "" + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3501,113 +3760,60 @@ ], "authors": [ { - "name": "Ignace Nyamagana Butera", - "email": "nyamsprod@gmail.com", - "homepage": "https://nyamsprod.com" + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" } ], - "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", - "homepage": "https://uri.thephpleague.com", - "keywords": [ - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc3986", - "rfc3987", - "rfc6570", - "uri", - "url", - "ws" - ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { - "docs": "https://uri.thephpleague.com", - "forum": "https://thephpleague.slack.com", - "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.1" + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2026-03-08T20:05:35+00:00" + "time": "2026-03-18T20:49:53+00:00" }, { - "name": "monolog/monolog", - "version": "3.10.0", + "name": "phpdocumentor/type-resolver", + "version": "2.0.0", "source": { "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", - "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/327a05bbee54120d4786a0dc67aad30226ad4cf9", + "reference": "327a05bbee54120d4786a0dc67aad30226ad4cf9", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/log": "^2.0 || ^3.0" - }, - "provide": { - "psr/log-implementation": "3.0.0" + "doctrine/deprecations": "^1.0", + "php": "^7.4 || ^8.0", + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^2.0" }, "require-dev": { - "aws/aws-sdk-php": "^3.0", - "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^7 || ^8", - "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2.0", - "guzzlehttp/guzzle": "^7.4.5", - "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8 || ^2.0", - "php-amqplib/php-amqplib": "~2.4 || ^3", - "php-console/php-console": "^3.1.8", - "phpstan/phpstan": "^2", - "phpstan/phpstan-deprecation-rules": "^2", - "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "^10.5.17 || ^11.0.7", - "predis/predis": "^1.1 || ^2", - "rollbar/rollbar": "^4.0", - "ruflin/elastica": "^7 || ^8", - "symfony/mailer": "^5.4 || ^6", - "symfony/mime": "^5.4 || ^6" - }, - "suggest": { - "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", - "doctrine/couchdb": "Allow sending log messages to a CouchDB server", - "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", - "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", - "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", - "ext-mbstring": "Allow to work properly with unicode symbols", - "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", - "ext-openssl": "Required to send log messages using SSL", - "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", - "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", - "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", - "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", - "rollbar/rollbar": "Allow sending log messages to Rollbar", - "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psalm/phar": "^4" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.x-dev" + "dev-1.x": "1.x-dev", + "dev-2.x": "2.x-dev" } }, "autoload": { "psr-4": { - "Monolog\\": "src/Monolog" + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3616,401 +3822,322 @@ ], "authors": [ { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "https://seld.be" + "name": "Mike van Riel", + "email": "me@mikevanriel.com" } ], - "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "https://github.com/Seldaek/monolog", - "keywords": [ - "log", - "logging", - "psr-3" - ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { - "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.10.0" + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/2.0.0" }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", - "type": "tidelift" - } - ], - "time": "2026-01-02T08:56:05+00:00" + "time": "2026-01-06T21:53:42+00:00" }, { - "name": "nesbot/carbon", - "version": "3.11.4", + "name": "phpoption/phpoption", + "version": "1.9.5", "source": { "type": "git", - "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60" + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/e890471a3494740f7d9326d72ce6a8c559ffee60", - "reference": "e890471a3494740f7d9326d72ce6a8c559ffee60", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", + "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", "shasum": "" }, "require": { - "carbonphp/carbon-doctrine-types": "<100.0", - "ext-json": "*", - "php": "^8.1", - "psr/clock": "^1.0", - "symfony/clock": "^6.3.12 || ^7.0 || ^8.0", - "symfony/polyfill-mbstring": "^1.0", - "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.0" - }, - "provide": { - "psr/clock-implementation": "1.0" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "doctrine/dbal": "^3.6.3 || ^4.0", - "doctrine/orm": "^2.15.2 || ^3.0", - "friendsofphp/php-cs-fixer": "^v3.87.1", - "kylekatarnls/multi-tester": "^2.5.3", - "phpmd/phpmd": "^2.15.0", - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.22", - "phpunit/phpunit": "^10.5.53", - "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.0" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" }, - "bin": [ - "bin/carbon" - ], "type": "library", "extra": { - "laravel": { - "providers": [ - "Carbon\\Laravel\\ServiceProvider" - ] - }, - "phpstan": { - "includes": [ - "extension.neon" - ] + "bamarni-bin": { + "bin-links": true, + "forward-command": false }, "branch-alias": { - "dev-2.x": "2.x-dev", - "dev-master": "3.x-dev" + "dev-master": "1.9-dev" } }, "autoload": { "psr-4": { - "Carbon\\": "src/Carbon/" + "PhpOption\\": "src/PhpOption/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "Apache-2.0" ], "authors": [ { - "name": "Brian Nesbitt", - "email": "brian@nesbot.com", - "homepage": "https://markido.com" + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" }, { - "name": "kylekatarnls", - "homepage": "https://github.com/kylekatarnls" + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" } ], - "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "https://carbonphp.github.io/carbon/", + "description": "Option Type for PHP", "keywords": [ - "date", - "datetime", - "time" + "language", + "option", + "php", + "type" ], "support": { - "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html", - "issues": "https://github.com/CarbonPHP/carbon/issues", - "source": "https://github.com/CarbonPHP/carbon" + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.5" }, "funding": [ { - "url": "https://github.com/sponsors/kylekatarnls", + "url": "https://github.com/GrahamCampbell", "type": "github" }, { - "url": "https://opencollective.com/Carbon#sponsor", - "type": "opencollective" - }, - { - "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", "type": "tidelift" } ], - "time": "2026-04-07T09:57:54+00:00" + "time": "2025-12-27T19:41:33+00:00" }, { - "name": "nette/schema", - "version": "v1.3.5", + "name": "phpseclib/phpseclib", + "version": "3.0.52", "source": { "type": "git", - "url": "https://github.com/nette/schema.git", - "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", - "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce", + "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce", "shasum": "" }, "require": { - "nette/utils": "^4.0", - "php": "8.1 - 8.5" + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" }, "require-dev": { - "nette/phpstan-rules": "^1.0", - "nette/tester": "^2.6", - "phpstan/extension-installer": "^1.4@stable", - "phpstan/phpstan": "^2.1.39@stable", - "tracy/tracy": "^2.8" + "phpunit/phpunit": "*" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-dev" - } + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." }, + "type": "library", "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], "psr-4": { - "Nette\\": "src" - }, - "classmap": [ - "src/" - ] + "phpseclib3\\": "phpseclib/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" + "MIT" ], "authors": [ { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" }, { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" } ], - "description": "📐 Nette Schema: validating data structures against a given Schema.", - "homepage": "https://nette.org", + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", "keywords": [ - "config", - "nette" + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" ], "support": { - "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.5" + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.52" }, - "time": "2026-02-23T03:47:12+00:00" + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2026-04-27T07:02:15+00:00" }, { - "name": "nette/utils", - "version": "v4.1.4", + "name": "phpstan/phpdoc-parser", + "version": "2.3.2", "source": { "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7" + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/7da6c396d7ebe142bc857c20479d5e70a5e1aac7", - "reference": "7da6c396d7ebe142bc857c20479d5e70a5e1aac7", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", + "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", "shasum": "" }, "require": { - "php": "8.2 - 8.5" - }, - "conflict": { - "nette/finder": "<3", - "nette/schema": "<1.2.2" + "php": "^7.4 || ^8.0" }, "require-dev": { - "jetbrains/phpstorm-attributes": "^1.2", - "nette/phpstan-rules": "^1.0", - "nette/tester": "^2.5", - "phpstan/extension-installer": "^1.4@stable", - "phpstan/phpstan": "^2.1@stable", - "tracy/tracy": "^2.9" - }, - "suggest": { - "ext-gd": "to use Image", - "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", - "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", - "ext-json": "to use Nette\\Utils\\Json", - "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^5.3.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", + "symfony/process": "^5.2" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1-dev" - } - }, "autoload": { "psr-4": { - "Nette\\": "src" - }, - "classmap": [ - "src/" - ] + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause", - "GPL-2.0-only", - "GPL-3.0-only" - ], - "authors": [ - { - "name": "David Grudl", - "homepage": "https://davidgrudl.com" - }, - { - "name": "Nette Community", - "homepage": "https://nette.org/contributors" - } - ], - "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", - "homepage": "https://nette.org", - "keywords": [ - "array", - "core", - "datetime", - "images", - "json", - "nette", - "paginator", - "password", - "slugify", - "string", - "unicode", - "utf-8", - "utility", - "validation" + "MIT" ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { - "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.1.4" + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" }, - "time": "2026-05-11T20:49:54+00:00" + "time": "2026-01-25T14:56:51+00:00" }, { - "name": "nikic/php-parser", - "version": "v5.7.0", + "name": "pragmarx/google2fa", + "version": "v9.0.0", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + "url": "https://github.com/antonioribeiro/google2fa.git", + "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/e6bc62dd6ae83acc475f57912e27466019a1f2cf", + "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" + "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0", + "php": "^7.1|^8.0" }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } + "require-dev": { + "phpstan/phpstan": "^1.9", + "phpunit/phpunit": "^7.5.15|^8.5|^9.0" }, + "type": "library", "autoload": { "psr-4": { - "PhpParser\\": "lib/PhpParser" + "PragmaRX\\Google2FA\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Antonio Carlos Ribeiro", + "email": "acr@antoniocarlosribeiro.com", + "role": "Creator & Designer" } ], - "description": "A PHP parser written in PHP", + "description": "A One Time Password Authentication package, compatible with Google Authenticator.", "keywords": [ - "parser", - "php" + "2fa", + "Authentication", + "Two Factor Authentication", + "google2fa" ], "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + "issues": "https://github.com/antonioribeiro/google2fa/issues", + "source": "https://github.com/antonioribeiro/google2fa/tree/v9.0.0" }, - "time": "2025-12-06T11:56:16+00:00" + "time": "2025-09-19T22:51:08+00:00" }, { - "name": "nunomaduro/termwind", - "version": "v2.3.3", + "name": "psr/clock", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/nunomaduro/termwind.git", - "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017" + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/6fb2a640ff502caace8e05fd7be3b503a7e1c017", - "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": "^8.2", - "symfony/console": "^7.3.6" - }, - "require-dev": { - "illuminate/console": "^11.46.1", - "laravel/pint": "^1.25.1", - "mockery/mockery": "^1.6.12", - "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.1.3", - "phpstan/phpstan": "^1.12.32", - "phpstan/phpstan-strict-rules": "^1.6.2", - "symfony/var-dumper": "^7.3.5", - "thecodingmachine/phpstan-strict-rules": "^1.0.0" + "php": "^7.0 || ^8.0" }, "type": "library", - "extra": { - "laravel": { - "providers": [ - "Termwind\\Laravel\\TermwindServiceProvider" - ] - }, - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, "autoload": { - "files": [ - "src/Functions.php" - ], "psr-4": { - "Termwind\\": "src/" + "Psr\\Clock\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4019,66 +4146,51 @@ ], "authors": [ { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Its like Tailwind CSS, but for the console.", + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", "keywords": [ - "cli", - "console", - "css", - "package", - "php", - "style" + "clock", + "now", + "psr", + "psr-20", + "time" ], "support": { - "issues": "https://github.com/nunomaduro/termwind/issues", - "source": "https://github.com/nunomaduro/termwind/tree/v2.3.3" + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://github.com/xiCO2k", - "type": "github" - } - ], - "time": "2025-11-20T02:34:59+00:00" + "time": "2022-11-25T14:36:26+00:00" }, { - "name": "paragonie/constant_time_encoding", - "version": "v3.1.3", + "name": "psr/container", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", - "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": "^8" - }, - "require-dev": { - "infection/infection": "^0", - "nikic/php-fuzzer": "^0", - "phpunit/phpunit": "^9|^10|^11", - "vimeo/psalm": "^4|^5|^6" + "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" + "Psr\\Container\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4087,188 +4199,154 @@ ], "authors": [ { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", "keywords": [ - "base16", - "base32", - "base32_decode", - "base32_encode", - "base64", - "base64_decode", - "base64_encode", - "bin2hex", - "encoding", - "hex", - "hex2bin", - "rfc4648" + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" ], "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "source": "https://github.com/paragonie/constant_time_encoding" + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2025-09-24T15:06:41+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { - "name": "paragonie/random_compat", - "version": "v9.99.100", + "name": "psr/event-dispatcher", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", "shasum": "" }, "require": { - "php": ">= 7" + "php": ">=7.2.0" }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } }, - "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "description": "Standard interfaces for event handling.", "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" + "events", + "psr", + "psr-14" ], "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" }, - "time": "2020-10-15T08:29:30+00:00" + "time": "2019-01-08T18:20:26+00:00" }, { - "name": "phpdocumentor/reflection", - "version": "6.3.0", + "name": "psr/http-client", + "version": "1.0.3", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/Reflection.git", - "reference": "d91b3270832785602adcc24ae2d0974ba99a8ff8" + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/d91b3270832785602adcc24ae2d0974ba99a8ff8", - "reference": "d91b3270832785602adcc24ae2d0974ba99a8ff8", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { - "composer-runtime-api": "^2", - "nikic/php-parser": "~4.18 || ^5.0", - "php": "8.1.*|8.2.*|8.3.*|8.4.*", - "phpdocumentor/reflection-common": "^2.1", - "phpdocumentor/reflection-docblock": "^5", - "phpdocumentor/type-resolver": "^1.2", - "symfony/polyfill-php80": "^1.28", - "webmozart/assert": "^1.7" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/coding-standard": "^13.0", - "eliashaeussler/phpunit-attributes": "^1.7", - "mikey179/vfsstream": "~1.2", - "mockery/mockery": "~1.6.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-webmozart-assert": "^1.2", - "phpunit/phpunit": "^10.0", - "psalm/phar": "^6.0", - "rector/rector": "^1.0.0", - "squizlabs/php_codesniffer": "^3.8" + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-5.x": "5.3.x-dev", - "dev-6.x": "6.0.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "files": [ - "src/php-parser/Modifiers.php" - ], "psr-4": { - "phpDocumentor\\": "src/phpDocumentor" + "Psr\\Http\\Client\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Reflection library to do Static Analysis for PHP Projects", - "homepage": "http://www.phpdoc.org", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", "keywords": [ - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" + "http", + "http-client", + "psr", + "psr-18" ], "support": { - "issues": "https://github.com/phpDocumentor/Reflection/issues", - "source": "https://github.com/phpDocumentor/Reflection/tree/6.3.0" + "source": "https://github.com/php-fig/http-client" }, - "time": "2025-06-06T13:39:18+00:00" + "time": "2023-09-23T14:17:50+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", + "name": "psr/http-factory", + "version": "1.1.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-2.x": "2.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src/" + "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4277,66 +4355,52 @@ ], "authors": [ { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2020-06-27T09:03:43+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "5.6.7", + "name": "psr/http-message", + "version": "2.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903" + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/31a105931bc8ffa3a123383829772e832fd8d903", - "reference": "31a105931bc8ffa3a123383829772e832fd8d903", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { - "doctrine/deprecations": "^1.1", - "ext-filter": "*", - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", - "webmozart/assert": "^1.9.1 || ^2" - }, - "require-dev": { - "mockery/mockery": "~1.3.5 || ~1.6.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-webmozart-assert": "^1.2", - "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src" + "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4345,60 +4409,51 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.7" + "source": "https://github.com/php-fig/http-message/tree/2.0" }, - "time": "2026-03-18T20:47:46+00:00" + "time": "2023-04-04T09:54:51+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "1.12.0", + "name": "psr/log", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", - "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4407,275 +4462,244 @@ ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2025-11-21T15:09:14+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { - "name": "phpoption/phpoption", - "version": "1.9.5", + "name": "psr/simple-cache", + "version": "3.0.0", "source": { "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", - "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" + "php": ">=8.0.0" }, "type": "library", "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": false - }, "branch-alias": { - "dev-master": "1.9-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { "psr-4": { - "PhpOption\\": "src/PhpOption/" + "Psr\\SimpleCache\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "Apache-2.0" + "MIT" ], "authors": [ { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Option Type for PHP", + "description": "Common interfaces for simple caching", "keywords": [ - "language", - "option", - "php", - "type" + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" ], "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.5" + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2025-12-27T19:41:33+00:00" + "time": "2021-10-29T13:26:27+00:00" }, { - "name": "phpseclib/phpseclib", - "version": "3.0.52", + "name": "psy/psysh", + "version": "v0.12.23", "source": { "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce" + "url": "https://github.com/bobthecow/psysh.git", + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2adaefc83df2ec548558307690f376dd7d4f4fce", - "reference": "2adaefc83df2ec548558307690f376dd7d4f4fce", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4dcc0f08047d52bbde475eda481146fd8e27e1a4", + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4", "shasum": "" }, "require": { - "paragonie/constant_time_encoding": "^1|^2|^3", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" }, "require-dev": { - "phpunit/phpunit": "*" + "bamarni/composer-bin-plugin": "^1.2", + "composer/class-map-generator": "^1.6" }, "suggest": { - "ext-dom": "Install the DOM extension to load XML formatted public keys.", - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "type": "library", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib3\\": "phpseclib/" - } + "composer/class-map-generator": "Improved tab completion performance with better class discovery.", + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" + "bin": [ + "bin/psysh" ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false, + "forward-command": false }, + "branch-alias": { + "dev-main": "0.12.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" + "name": "Justin Hileman", + "email": "justin@justinhileman.info" } ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", + "description": "An interactive shell for modern PHP.", + "homepage": "https://psysh.org", "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" + "REPL", + "console", + "interactive", + "shell" ], "support": { - "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.52" + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.23" }, - "funding": [ - { - "url": "https://github.com/terrafrost", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpseclib", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", - "type": "tidelift" - } - ], - "time": "2026-04-27T07:02:15+00:00" + "time": "2026-05-23T13:41:31+00:00" }, { - "name": "phpstan/phpdoc-parser", - "version": "2.3.2", + "name": "ralouphie/getallheaders", + "version": "3.0.3", "source": { "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a" + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a", - "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0" + "php": ">=5.6" }, "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^5.3.0", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6", - "symfony/process": "^5.2" + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" }, "type": "library", "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } + "files": [ + "src/getallheaders.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2" + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" }, - "time": "2026-01-25T14:56:51+00:00" + "time": "2019-03-08T08:55:37+00:00" }, { - "name": "pragmarx/google2fa", - "version": "v8.0.3", + "name": "ramsey/collection", + "version": "2.1.1", "source": { "type": "git", - "url": "https://github.com/antonioribeiro/google2fa.git", - "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad" + "url": "https://github.com/ramsey/collection.git", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad", - "reference": "6f8d87ebd5afbf7790bde1ffc7579c7c705e0fad", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", "shasum": "" }, "require": { - "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0", - "php": "^7.1|^8.0" + "php": "^8.1" }, "require-dev": { - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^7.5.15|^8.5|^9.0" + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" }, "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, "autoload": { "psr-4": { - "PragmaRX\\Google2FA\\": "src/" + "Ramsey\\Collection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4684,98 +4708,138 @@ ], "authors": [ { - "name": "Antonio Carlos Ribeiro", - "email": "acr@antoniocarlosribeiro.com", - "role": "Creator & Designer" + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" } ], - "description": "A One Time Password Authentication package, compatible with Google Authenticator.", + "description": "A PHP library for representing and manipulating collections.", "keywords": [ - "2fa", - "Authentication", - "Two Factor Authentication", - "google2fa" + "array", + "collection", + "hash", + "map", + "queue", + "set" ], "support": { - "issues": "https://github.com/antonioribeiro/google2fa/issues", - "source": "https://github.com/antonioribeiro/google2fa/tree/v8.0.3" + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.1.1" }, - "time": "2024-09-05T11:56:40+00:00" + "time": "2025-03-22T05:38:12+00:00" }, { - "name": "psr/clock", - "version": "1.0.0", + "name": "ramsey/uuid", + "version": "4.9.2", "source": { "type": "git", - "url": "https://github.com/php-fig/clock.git", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + "url": "https://github.com/ramsey/uuid.git", + "reference": "8429c78ca35a09f27565311b98101e2826affde0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", - "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", + "reference": "8429c78ca35a09f27565311b98101e2826affde0", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0" + "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.25", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, "autoload": { + "files": [ + "src/functions.php" + ], "psr-4": { - "Psr\\Clock\\": "src/" + "Ramsey\\Uuid\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for reading the clock.", - "homepage": "https://github.com/php-fig/clock", + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", "keywords": [ - "clock", - "now", - "psr", - "psr-20", - "time" + "guid", + "identifier", + "uuid" ], "support": { - "issues": "https://github.com/php-fig/clock/issues", - "source": "https://github.com/php-fig/clock/tree/1.0.0" + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.9.2" }, - "time": "2022-11-25T14:36:26+00:00" + "time": "2025-12-14T04:43:48+00:00" }, { - "name": "psr/container", - "version": "2.0.2", + "name": "roave/better-reflection", + "version": "6.71.0", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + "url": "https://github.com/Roave/BetterReflection.git", + "reference": "3ec176d4a161b4e8764edc625d69ff624ca390b1" }, "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "type": "zip", + "url": "https://api.github.com/repos/Roave/BetterReflection/zipball/3ec176d4a161b4e8764edc625d69ff624ca390b1", + "reference": "3ec176d4a161b4e8764edc625d69ff624ca390b1", "shasum": "" }, "require": { - "php": ">=7.4.0" + "ext-json": "*", + "jetbrains/phpstorm-stubs": "2026.1", + "nikic/php-parser": "^5.7.0", + "php": "~8.4.1 || ~8.5.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } + "conflict": { + "thecodingmachine/safe": "<1.1.3" + }, + "require-dev": { + "phpbench/phpbench": "^1.6.1", + "phpunit/phpunit": "^13.1.8" + }, + "suggest": { + "composer/composer": "Required to use the ComposerSourceLocator" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "Roave\\BetterReflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4784,51 +4848,69 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "James Titcumb", + "email": "james@asgrim.com", + "homepage": "https://github.com/asgrim" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + }, + { + "name": "Gary Hockin", + "email": "gary@roave.com", + "homepage": "https://github.com/geeh" + }, + { + "name": "Jaroslav Hanslík", + "email": "kukulich@kukulich.cz", + "homepage": "https://github.com/kukulich" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], + "description": "Better Reflection - an improved code reflection API", "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" + "issues": "https://github.com/Roave/BetterReflection/issues", + "source": "https://github.com/Roave/BetterReflection/tree/6.71.0" }, - "time": "2021-11-05T16:47:00+00:00" + "time": "2026-05-02T10:56:00+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "spatie/eloquent-sortable", + "version": "4.5.2", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/spatie/eloquent-sortable.git", + "reference": "c1c4f3a66cd41eb7458783c8a4c8e5d7924a9f20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/c1c4f3a66cd41eb7458783c8a4c8e5d7924a9f20", + "reference": "c1c4f3a66cd41eb7458783c8a4c8e5d7924a9f20", "shasum": "" }, "require": { - "php": ">=7.2.0" + "illuminate/database": "^9.31|^10.0|^11.0|^12.0", + "illuminate/support": "^9.31|^10.0|^11.0|^12.0", + "nesbot/carbon": "^2.63|^3.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.9" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.5|^10.0|^11.5.3" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" + "laravel": { + "providers": [ + "Spatie\\EloquentSortable\\EloquentSortableServiceProvider" + ] } }, "autoload": { "psr-4": { - "Psr\\EventDispatcher\\": "src/" + "Spatie\\EloquentSortable\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4837,49 +4919,63 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Freek Van der Herten", + "email": "freek@spatie.be" } ], - "description": "Standard interfaces for event handling.", + "description": "Sortable behaviour for eloquent models", + "homepage": "https://github.com/spatie/eloquent-sortable", "keywords": [ - "events", - "psr", - "psr-14" + "behaviour", + "eloquent", + "laravel", + "model", + "sort", + "sortable" ], "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "issues": "https://github.com/spatie/eloquent-sortable/issues", + "source": "https://github.com/spatie/eloquent-sortable/tree/4.5.2" }, - "time": "2019-01-08T18:20:26+00:00" + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-08-25T11:46:57+00:00" }, { - "name": "psr/http-client", - "version": "1.0.3", + "name": "spatie/file-system-watcher", + "version": "1.2.1", "source": { "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + "url": "https://github.com/spatie/file-system-watcher.git", + "reference": "2fe96de88af6660b3ab7658a8f1d41b10ad0aff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", - "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "url": "https://api.github.com/repos/spatie/file-system-watcher/zipball/2fe96de88af6660b3ab7658a8f1d41b10ad0aff6", + "reference": "2fe96de88af6660b3ab7658a8f1d41b10ad0aff6", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0 || ^2.0" + "php": "^8.3", + "symfony/process": "^7.0|^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "pestphp/pest": "^4.0", + "spatie/ray": "^1.22", + "spatie/temporary-directory": "^2.0" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Http\\Client\\": "src/" + "Spatie\\Watcher\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4888,50 +4984,81 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" } ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", + "description": "Watch changes in the file system using PHP", + "homepage": "https://github.com/spatie/file-system-watcher", "keywords": [ - "http", - "http-client", - "psr", - "psr-18" + "file-system-watcher", + "spatie" ], "support": { - "source": "https://github.com/php-fig/http-client" + "issues": "https://github.com/spatie/file-system-watcher/issues", + "source": "https://github.com/spatie/file-system-watcher/tree/1.2.1" }, - "time": "2023-09-23T14:17:50+00:00" + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-11-26T10:41:42+00:00" }, { - "name": "psr/http-factory", - "version": "1.1.0", + "name": "spatie/laravel-data", + "version": "4.23.0", "source": { "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + "url": "https://github.com/spatie/laravel-data.git", + "reference": "230543769c996e407fec2873930626aed7dd0d3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", - "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "url": "https://api.github.com/repos/spatie/laravel-data/zipball/230543769c996e407fec2873930626aed7dd0d3b", + "reference": "230543769c996e407fec2873930626aed7dd0d3b", "shasum": "" }, "require": { - "php": ">=7.1", - "psr/http-message": "^1.0 || ^2.0" + "illuminate/contracts": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.1", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/reflection-docblock": "^5.3 || ^6.0", + "phpdocumentor/type-resolver": "^1.7 || ^2.0", + "spatie/laravel-package-tools": "^1.9.0", + "spatie/php-structure-discoverer": "^2.0" + }, + "require-dev": { + "fakerphp/faker": "^1.14", + "friendsofphp/php-cs-fixer": "^3.0", + "inertiajs/inertia-laravel": "^2.0|^3.0", + "livewire/livewire": "^3.0|^4.0", + "mockery/mockery": "^1.6", + "nesbot/carbon": "^2.63|^3.0", + "orchestra/testbench": "^8.37.0|^9.16|^10.9|^11.0", + "pestphp/pest": "^2.36|^3.8|^4.3", + "pestphp/pest-plugin-laravel": "^2.4|^3.0|^4.0", + "pestphp/pest-plugin-livewire": "^2.1|^3.0|^4.0", + "phpbench/phpbench": "^1.2", + "phpstan/extension-installer": "^1.1", + "spatie/invade": "^1.0", + "spatie/laravel-typescript-transformer": "^2.5", + "spatie/pest-plugin-snapshots": "^2.1", + "spatie/test-time": "^1.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" + "laravel": { + "providers": [ + "Spatie\\LaravelData\\LaravelDataServiceProvider" + ] } }, "autoload": { "psr-4": { - "Psr\\Http\\Message\\": "src/" + "Spatie\\LaravelData\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -4940,52 +5067,60 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Ruben Van Assche", + "email": "ruben@spatie.be", + "role": "Developer" } ], - "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "description": "Create unified resources and data transfer objects", + "homepage": "https://github.com/spatie/laravel-data", "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" + "laravel", + "laravel-data", + "spatie" ], "support": { - "source": "https://github.com/php-fig/http-factory" + "issues": "https://github.com/spatie/laravel-data/issues", + "source": "https://github.com/spatie/laravel-data/tree/4.23.0" }, - "time": "2024-04-15T12:06:14+00:00" + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-05-08T14:41:13+00:00" }, { - "name": "psr/http-message", - "version": "2.0", + "name": "spatie/laravel-package-tools", + "version": "1.93.1", "source": { "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "d5552849801f2642aea710557463234b59ef65eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d5552849801f2642aea710557463234b59ef65eb", + "reference": "d5552849801f2642aea710557463234b59ef65eb", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "illuminate/contracts": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.1" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^8.0|^9.2|^10.0|^11.0", + "pestphp/pest": "^2.1|^3.1|^4.0", + "phpunit/php-code-coverage": "^10.0|^11.0|^12.0", + "phpunit/phpunit": "^10.5|^11.5|^12.5", + "spatie/pest-plugin-test-time": "^2.2|^3.0" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Http\\Message\\": "src/" + "Spatie\\LaravelPackageTools\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4994,51 +5129,75 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" } ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" + "laravel-package-tools", + "spatie" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.93.1" }, - "time": "2023-04-04T09:54:51+00:00" + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-05-19T14:06:37+00:00" }, { - "name": "psr/log", - "version": "3.0.2", + "name": "spatie/laravel-passkeys", + "version": "1.8.1", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + "url": "https://github.com/spatie/laravel-passkeys.git", + "reference": "a9208c4c8f501c98392fd4db4ca719e30c9c7861" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "url": "https://api.github.com/repos/spatie/laravel-passkeys/zipball/a9208c4c8f501c98392fd4db4ca719e30c9c7861", + "reference": "a9208c4c8f501c98392fd4db4ca719e30c9c7861", "shasum": "" }, "require": { - "php": ">=8.0.0" + "illuminate/contracts": "^11.0|^12.0|^13.0", + "php": "^8.2|^8.3|^8.4", + "spatie/laravel-package-tools": "^1.16", + "web-auth/webauthn-lib": "^5.3" + }, + "require-dev": { + "larastan/larastan": "^3.4", + "laravel/pint": "^1.14", + "livewire/livewire": "^3.5 || ^4.0", + "nunomaduro/collision": "^8.1.1", + "orchestra/testbench": "^10.0|^11.0", + "pestphp/pest": "^3.0|^4.0", + "pestphp/pest-plugin-arch": "^3.0|^4.0", + "pestphp/pest-plugin-laravel": "^3.0|^4.0", + "phpstan/extension-installer": "^1.3", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "spatie/laravel-ray": "^1.35" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "3.x-dev" + "laravel": { + "providers": [ + "Spatie\\LaravelPasskeys\\LaravelPasskeysServiceProvider" + ] } }, "autoload": { "psr-4": { - "Psr\\Log\\": "src" + "Spatie\\LaravelPasskeys\\": "src/", + "Spatie\\LaravelPasskeys\\Database\\Factories\\": "database/factories/" } }, "notification-url": "https://packagist.org/downloads/", @@ -5047,48 +5206,72 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Use passkeys in your Laravel app", + "homepage": "https://github.com/spatie/laravel-passkeys", "keywords": [ - "log", - "psr", - "psr-3" + "laravel", + "laravel-passkeys", + "spatie" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" + "issues": "https://github.com/spatie/laravel-passkeys/issues", + "source": "https://github.com/spatie/laravel-passkeys/tree/1.8.1" }, - "time": "2024-09-11T13:17:53+00:00" + "funding": [ + { + "url": "https://github.com/Spatie", + "type": "github" + } + ], + "time": "2026-06-05T16:43:48+00:00" }, { - "name": "psr/simple-cache", - "version": "3.0.0", + "name": "spatie/laravel-query-builder", + "version": "6.4.4", "source": { "type": "git", - "url": "https://github.com/php-fig/simple-cache.git", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + "url": "https://github.com/spatie/laravel-query-builder.git", + "reference": "ab9c4c369fc913d6c020a0f6776f3c82f3e523fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", - "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/ab9c4c369fc913d6c020a0f6776f3c82f3e523fb", + "reference": "ab9c4c369fc913d6c020a0f6776f3c82f3e523fb", "shasum": "" }, "require": { - "php": ">=8.0.0" + "illuminate/database": "^10.0|^11.0|^12.0|^13.0", + "illuminate/http": "^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^10.0|^11.0|^12.0|^13.0", + "php": "^8.2", + "spatie/laravel-package-tools": "^1.11" + }, + "require-dev": { + "ext-json": "*", + "larastan/larastan": "^2.7 || ^3.3", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^7.0|^8.0|^10.0|^11.0", + "pestphp/pest": "^2.0|^3.7|^4.0", + "phpunit/phpunit": "^10.0|^11.5.3|^12.0", + "spatie/invade": "^2.0" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "3.0.x-dev" + "laravel": { + "providers": [ + "Spatie\\QueryBuilder\\QueryBuilderServiceProvider" + ] } }, "autoload": { "psr-4": { - "Psr\\SimpleCache\\": "src/" + "Spatie\\QueryBuilder\\": "src", + "Spatie\\QueryBuilder\\Database\\Factories\\": "database/factories" } }, "notification-url": "https://packagist.org/downloads/", @@ -5097,76 +5280,79 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Alex Vanderbist", + "email": "alex@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" } ], - "description": "Common interfaces for simple caching", + "description": "Easily build Eloquent queries from API requests", + "homepage": "https://github.com/spatie/laravel-query-builder", "keywords": [ - "cache", - "caching", - "psr", - "psr-16", - "simple-cache" + "laravel-query-builder", + "spatie" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + "issues": "https://github.com/spatie/laravel-query-builder/issues", + "source": "https://github.com/spatie/laravel-query-builder" }, - "time": "2021-10-29T13:26:27+00:00" + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + } + ], + "time": "2026-03-08T13:45:05+00:00" }, { - "name": "psy/psysh", - "version": "v0.12.21", + "name": "spatie/laravel-settings", + "version": "3.9.0", "source": { "type": "git", - "url": "https://github.com/bobthecow/psysh.git", - "reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97" + "url": "https://github.com/spatie/laravel-settings.git", + "reference": "6c1351cf57c4ae96cd2313ae395c6d367dfeee01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4821fab5b7cd8c49a673a9fd5754dc9162bb9e97", - "reference": "4821fab5b7cd8c49a673a9fd5754dc9162bb9e97", + "url": "https://api.github.com/repos/spatie/laravel-settings/zipball/6c1351cf57c4ae96cd2313ae395c6d367dfeee01", + "reference": "6c1351cf57c4ae96cd2313ae395c6d367dfeee01", "shasum": "" }, "require": { "ext-json": "*", - "ext-tokenizer": "*", - "nikic/php-parser": "^5.0 || ^4.0", - "php": "^8.0 || ^7.4", - "symfony/console": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", - "symfony/var-dumper": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" - }, - "conflict": { - "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + "illuminate/database": "^11.0|^12.0|^13.0", + "php": "^8.2", + "phpdocumentor/type-resolver": "^1.5|^2.0", + "spatie/temporary-directory": "^1.3|^2.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.2", - "composer/class-map-generator": "^1.6" + "ext-redis": "*", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^9.0|^10.0|^11.0", + "pestphp/pest": "^2.0|^3.0|^4.0", + "pestphp/pest-plugin-laravel": "^2.0|^3.0|^4.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/laravel-data": "^2.0.0|^4.0.0", + "spatie/pest-plugin-snapshots": "^2.0", + "spatie/phpunit-snapshot-assertions": "^4.2|^5.0", + "spatie/ray": "^1.36" }, "suggest": { - "composer/class-map-generator": "Improved tab completion performance with better class discovery.", - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." + "spatie/data-transfer-object": "Allows for DTO casting to settings. (deprecated)" }, - "bin": [ - "bin/psysh" - ], "type": "library", "extra": { - "bamarni-bin": { - "bin-links": false, - "forward-command": false - }, - "branch-alias": { - "dev-main": "0.12.x-dev" + "laravel": { + "providers": [ + "Spatie\\LaravelSettings\\LaravelSettingsServiceProvider" + ] } }, "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Psy\\": "src/" + "Spatie\\LaravelSettings\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -5175,50 +5361,77 @@ ], "authors": [ { - "name": "Justin Hileman", - "email": "justin@justinhileman.info" + "name": "Ruben Van Assche", + "email": "ruben@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" } ], - "description": "An interactive shell for modern PHP.", - "homepage": "https://psysh.org", + "description": "Store your application settings", + "homepage": "https://github.com/spatie/laravel-settings", "keywords": [ - "REPL", - "console", - "interactive", - "shell" + "laravel-settings", + "spatie" ], "support": { - "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.21" + "issues": "https://github.com/spatie/laravel-settings/issues", + "source": "https://github.com/spatie/laravel-settings/tree/3.9.0" }, - "time": "2026-03-06T21:21:28+00:00" + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-05-26T13:18:06+00:00" }, { - "name": "ralouphie/getallheaders", - "version": "3.0.3", + "name": "spatie/laravel-typescript-transformer", + "version": "3.2.0", "source": { "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" + "url": "https://github.com/spatie/laravel-typescript-transformer.git", + "reference": "53ce01151bda3727de95f59549d4151b87c34a52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", + "url": "https://api.github.com/repos/spatie/laravel-typescript-transformer/zipball/53ce01151bda3727de95f59549d4151b87c34a52", + "reference": "53ce01151bda3727de95f59549d4151b87c34a52", "shasum": "" }, "require": { - "php": ">=5.6" + "illuminate/contracts": "^11.0|^12.0|^13.0", + "php": "^8.2", + "spatie/typescript-transformer": "^3.0" }, "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" + "friendsofphp/php-cs-fixer": "^3.0", + "orchestra/testbench": "^9.0|^10.0|^11.0", + "pestphp/pest": "^3.0|^4.2", + "pestphp/pest-plugin-arch": "^3.0|^4.0", + "pestphp/pest-plugin-laravel": "^3.0|^4.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "spatie/laravel-data": "^4.0" }, "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelTypeScriptTransformer\\TypeScriptTransformerServiceProvider" + ] + } + }, "autoload": { - "files": [ - "src/getallheaders.php" - ] + "psr-4": { + "Spatie\\LaravelTypeScriptTransformer\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5226,65 +5439,80 @@ ], "authors": [ { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" + "name": "Ruben Van Assche", + "email": "ruben@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" } ], - "description": "A polyfill for getallheaders.", + "description": "Transform your PHP structures to TypeScript types", + "homepage": "https://github.com/spatie/typescript-transformer", + "keywords": [ + "spatie", + "typescript-transformer" + ], "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" + "issues": "https://github.com/spatie/laravel-typescript-transformer/issues", + "source": "https://github.com/spatie/laravel-typescript-transformer/tree/3.2.0" }, - "time": "2019-03-08T08:55:37+00:00" + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-05-08T12:48:32+00:00" }, { - "name": "ramsey/collection", - "version": "2.1.1", + "name": "spatie/php-structure-discoverer", + "version": "2.4.2", "source": { "type": "git", - "url": "https://github.com/ramsey/collection.git", - "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" + "url": "https://github.com/spatie/php-structure-discoverer.git", + "reference": "10cd4e0018450d23e2bd8f8472569ad0c445c0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", - "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", + "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/10cd4e0018450d23e2bd8f8472569ad0c445c0fc", + "reference": "10cd4e0018450d23e2bd8f8472569ad0c445c0fc", "shasum": "" }, "require": { - "php": "^8.1" + "illuminate/collections": "^11.0|^12.0|^13.0", + "php": "^8.3", + "spatie/laravel-package-tools": "^1.92.7", + "symfony/finder": "^6.0|^7.3.5|^8.0" }, "require-dev": { - "captainhook/plugin-composer": "^5.3", - "ergebnis/composer-normalize": "^2.45", - "fakerphp/faker": "^1.24", - "hamcrest/hamcrest-php": "^2.0", - "jangregor/phpstan-prophecy": "^2.1", - "mockery/mockery": "^1.6", - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.4", - "phpspec/prophecy-phpunit": "^2.3", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-mockery": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^10.5", - "ramsey/coding-standard": "^2.3", - "ramsey/conventional-commits": "^1.6", - "roave/security-advisories": "dev-latest" + "amphp/parallel": "^2.3.2", + "illuminate/console": "^11.0|^12.0|^13.0", + "nunomaduro/collision": "^7.0|^8.8.3", + "orchestra/testbench": "^9.5|^10.8|^11.0", + "pestphp/pest": "^3.8|^4.0", + "pestphp/pest-plugin-laravel": "^3.2|^4.0", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan-deprecation-rules": "^1.2.1", + "phpstan/phpstan-phpunit": "^1.4.2", + "spatie/laravel-ray": "^1.43.1" + }, + "suggest": { + "amphp/parallel": "When you want to use the Parallel discover worker" }, "type": "library", "extra": { - "captainhook": { - "force-install": true - }, - "ramsey/conventional-commits": { - "configFile": "conventional-commits.json" + "laravel": { + "providers": [ + "Spatie\\StructureDiscoverer\\StructureDiscovererServiceProvider" + ] } }, "autoload": { "psr-4": { - "Ramsey\\Collection\\": "src/" + "Spatie\\StructureDiscoverer\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -5293,136 +5521,129 @@ ], "authors": [ { - "name": "Ben Ramsey", - "email": "ben@benramsey.com", - "homepage": "https://benramsey.com" + "name": "Ruben Van Assche", + "email": "ruben@spatie.be", + "role": "Developer" } ], - "description": "A PHP library for representing and manipulating collections.", + "description": "Automatically discover structures within your PHP application", + "homepage": "https://github.com/spatie/php-structure-discoverer", "keywords": [ - "array", - "collection", - "hash", - "map", - "queue", - "set" + "discover", + "laravel", + "php", + "php-structure-discoverer" ], "support": { - "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/2.1.1" + "issues": "https://github.com/spatie/php-structure-discoverer/issues", + "source": "https://github.com/spatie/php-structure-discoverer/tree/2.4.2" }, - "time": "2025-03-22T05:38:12+00:00" + "funding": [ + { + "url": "https://github.com/LaravelAutoDiscoverer", + "type": "github" + } + ], + "time": "2026-04-28T06:26:02+00:00" }, { - "name": "ramsey/uuid", - "version": "4.9.2", + "name": "spatie/temporary-directory", + "version": "2.4.0", "source": { "type": "git", - "url": "https://github.com/ramsey/uuid.git", - "reference": "8429c78ca35a09f27565311b98101e2826affde0" + "url": "https://github.com/spatie/temporary-directory.git", + "reference": "32cbb9645b28839cf4f476708e99a2c70e6802c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", - "reference": "8429c78ca35a09f27565311b98101e2826affde0", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/32cbb9645b28839cf4f476708e99a2c70e6802c9", + "reference": "32cbb9645b28839cf4f476708e99a2c70e6802c9", "shasum": "" }, - "require": { - "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", - "php": "^8.0", - "ramsey/collection": "^1.2 || ^2.0" - }, - "replace": { - "rhumsaa/uuid": "self.version" + "require": { + "php": "^8.0" }, "require-dev": { - "captainhook/captainhook": "^5.25", - "captainhook/plugin-composer": "^5.3", - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "ergebnis/composer-normalize": "^2.47", - "mockery/mockery": "^1.6", - "paragonie/random-lib": "^2", - "php-mock/php-mock": "^2.6", - "php-mock/php-mock-mockery": "^1.5", - "php-parallel-lint/php-parallel-lint": "^1.4.0", - "phpbench/phpbench": "^1.2.14", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.1", - "phpstan/phpstan-mockery": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpunit/phpunit": "^9.6", - "slevomat/coding-standard": "^8.18", - "squizlabs/php_codesniffer": "^3.13" - }, - "suggest": { - "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", - "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", - "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", - "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + "phpunit/phpunit": "^9.5" }, "type": "library", - "extra": { - "captainhook": { - "force-install": true - } - }, "autoload": { - "files": [ - "src/functions.php" - ], "psr-4": { - "Ramsey\\Uuid\\": "src/" + "Spatie\\TemporaryDirectory\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "authors": [ + { + "name": "Alex Vanderbist", + "email": "alex@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Easily create, use and destroy temporary directories", + "homepage": "https://github.com/spatie/temporary-directory", "keywords": [ - "guid", - "identifier", - "uuid" + "php", + "spatie", + "temporary-directory" ], "support": { - "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.2" + "issues": "https://github.com/spatie/temporary-directory/issues", + "source": "https://github.com/spatie/temporary-directory/tree/2.4.0" }, - "time": "2025-12-14T04:43:48+00:00" + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-06-22T07:55:44+00:00" }, { - "name": "revolt/event-loop", - "version": "v1.0.7", + "name": "spatie/typescript-transformer", + "version": "3.2.0", "source": { "type": "git", - "url": "https://github.com/revoltphp/event-loop.git", - "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3" + "url": "https://github.com/spatie/typescript-transformer.git", + "reference": "bf8ae5952268020ae229a572248b78c253d18554" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/revoltphp/event-loop/zipball/09bf1bf7f7f574453efe43044b06fafe12216eb3", - "reference": "09bf1bf7f7f574453efe43044b06fafe12216eb3", + "url": "https://api.github.com/repos/spatie/typescript-transformer/zipball/bf8ae5952268020ae229a572248b78c253d18554", + "reference": "bf8ae5952268020ae229a572248b78c253d18554", "shasum": "" }, "require": { - "php": ">=8.1" + "php": "^8.2", + "phpstan/phpdoc-parser": "^2.3", + "roave/better-reflection": "^6.41", + "spatie/file-system-watcher": "^1.1", + "spatie/php-structure-discoverer": "^2.2", + "symfony/process": "^7.0|^8.0" }, "require-dev": { - "ext-json": "*", - "jetbrains/phpstorm-stubs": "^2019.3", - "phpunit/phpunit": "^9", - "psalm/phar": "^5.15" + "friendsofphp/php-cs-fixer": "^3.0", + "pestphp/pest": "^3.0|^4.0", + "pestphp/pest-plugin-arch": "^3.0|^4.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "spatie/ray": "^1.41", + "spatie/temporary-directory": "^2.1" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.x-dev" - } - }, "autoload": { "psr-4": { - "Revolt\\": "src" + "Spatie\\TypeScriptTransformer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -5431,74 +5652,62 @@ ], "authors": [ { - "name": "Aaron Piotrowski", - "email": "aaron@trowski.com" - }, - { - "name": "Cees-Jan Kiewiet", - "email": "ceesjank@gmail.com" - }, - { - "name": "Christian Lück", - "email": "christian@clue.engineering" - }, - { - "name": "Niklas Keller", - "email": "me@kelunik.com" + "name": "Ruben Van Assche", + "email": "ruben@spatie.be", + "role": "Developer" } ], - "description": "Rock-solid event loop for concurrent PHP applications.", + "description": "This is my package typescript-transformer", + "homepage": "https://github.com/spatie/typescript-transformer", "keywords": [ - "async", - "asynchronous", - "concurrency", - "event", - "event-loop", - "non-blocking", - "scheduler" + "spatie", + "typescript-transformer" ], "support": { - "issues": "https://github.com/revoltphp/event-loop/issues", - "source": "https://github.com/revoltphp/event-loop/tree/v1.0.7" + "issues": "https://github.com/spatie/typescript-transformer/issues", + "source": "https://github.com/spatie/typescript-transformer/tree/3.2.0" }, - "time": "2025-01-25T19:27:39+00:00" + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2026-05-08T11:43:20+00:00" }, { - "name": "spatie/eloquent-sortable", - "version": "4.5.0", + "name": "spomky-labs/cbor-php", + "version": "3.2.3", "source": { "type": "git", - "url": "https://github.com/spatie/eloquent-sortable.git", - "reference": "76c8fbc79e1d5eec85e7145e46c7f0a65e1f4cda" + "url": "https://github.com/Spomky-Labs/cbor-php.git", + "reference": "dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/76c8fbc79e1d5eec85e7145e46c7f0a65e1f4cda", - "reference": "76c8fbc79e1d5eec85e7145e46c7f0a65e1f4cda", + "url": "https://api.github.com/repos/Spomky-Labs/cbor-php/zipball/dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32", + "reference": "dd6eb84e6d92f7b8bd0da56b4b4dd7235aed0c32", "shasum": "" }, "require": { - "illuminate/database": "^9.31|^10.0|^11.0|^12.0", - "illuminate/support": "^9.31|^10.0|^11.0|^12.0", - "nesbot/carbon": "^2.63|^3.0", - "php": "^8.1", - "spatie/laravel-package-tools": "^1.9" + "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17", + "ext-mbstring": "*", + "php": ">=8.0" }, "require-dev": { - "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", - "phpunit/phpunit": "^9.5|^10.0|^11.5.3" + "ext-json": "*", + "roave/security-advisories": "dev-latest", + "symfony/error-handler": "^6.4|^7.1|^8.0", + "symfony/var-dumper": "^6.4|^7.1|^8.0" }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Spatie\\EloquentSortable\\EloquentSortableServiceProvider" - ] - } + "suggest": { + "ext-bcmath": "GMP or BCMath extensions will drastically improve the library performance. BCMath extension needed to handle the Big Float and Decimal Fraction Tags", + "ext-gmp": "GMP or BCMath extensions will drastically improve the library performance" }, + "type": "library", "autoload": { "psr-4": { - "Spatie\\EloquentSortable\\": "src/" + "CBOR\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -5507,63 +5716,83 @@ ], "authors": [ { - "name": "Freek Van der Herten", - "email": "freek@spatie.be" + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/Spomky-Labs/cbor-php/contributors" } ], - "description": "Sortable behaviour for eloquent models", - "homepage": "https://github.com/spatie/eloquent-sortable", + "description": "CBOR Encoder/Decoder for PHP", "keywords": [ - "behaviour", - "eloquent", - "laravel", - "model", - "sort", - "sortable" + "Concise Binary Object Representation", + "RFC7049", + "cbor" ], "support": { - "issues": "https://github.com/spatie/eloquent-sortable/issues", - "source": "https://github.com/spatie/eloquent-sortable/tree/4.5.0" + "issues": "https://github.com/Spomky-Labs/cbor-php/issues", + "source": "https://github.com/Spomky-Labs/cbor-php/tree/3.2.3" }, "funding": [ { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" + "url": "https://github.com/Spomky", + "type": "github" }, { - "url": "https://github.com/spatie", - "type": "github" + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" } ], - "time": "2025-06-03T12:41:10+00:00" + "time": "2026-04-01T12:15:20+00:00" }, { - "name": "spatie/fractalistic", - "version": "2.11.0", + "name": "spomky-labs/pki-framework", + "version": "1.4.2", "source": { "type": "git", - "url": "https://github.com/spatie/fractalistic.git", - "reference": "046c535f30b31a9356fc034ce75e8ee74614ed4f" + "url": "https://github.com/Spomky-Labs/pki-framework.git", + "reference": "aa576cbd07128075bef97ac2f8af9854e67513d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/fractalistic/zipball/046c535f30b31a9356fc034ce75e8ee74614ed4f", - "reference": "046c535f30b31a9356fc034ce75e8ee74614ed4f", + "url": "https://api.github.com/repos/Spomky-Labs/pki-framework/zipball/aa576cbd07128075bef97ac2f8af9854e67513d8", + "reference": "aa576cbd07128075bef97ac2f8af9854e67513d8", "shasum": "" }, "require": { - "league/fractal": "^0.20.1", - "php": "^7.4|^8.0" + "brick/math": "^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17", + "ext-mbstring": "*", + "php": ">=8.1", + "psr/clock": "^1.0" }, "require-dev": { - "illuminate/pagination": "~5.3.0|~5.4.0|^9.0", - "pestphp/pest": "^1.22", - "phpunit/phpunit": "^9.0" + "ekino/phpstan-banned-code": "^1.0|^2.0|^3.0", + "ext-gmp": "*", + "ext-openssl": "*", + "infection/infection": "^0.28|^0.29|^0.31|^0.32", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpstan/extension-installer": "^1.3|^2.0", + "phpstan/phpstan": "^1.8|^2.0", + "phpstan/phpstan-deprecation-rules": "^1.0|^2.0", + "phpstan/phpstan-phpunit": "^1.1|^2.0", + "phpstan/phpstan-strict-rules": "^1.3|^2.0", + "phpunit/phpunit": "^10.1|^11.0|^12.0|^13.0", + "rector/rector": "^1.0|^2.0", + "roave/security-advisories": "dev-latest", + "symfony/string": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0", + "symplify/easy-coding-standard": "^12.0|^13.0" + }, + "suggest": { + "ext-bcmath": "For better performance (or GMP)", + "ext-gmp": "For better performance (or BCMath)", + "ext-openssl": "For OpenSSL based cyphering" }, "type": "library", "autoload": { "psr-4": { - "Spatie\\Fractalistic\\": "src" + "SpomkyLabs\\Pki\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -5572,84 +5801,103 @@ ], "authors": [ { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Original developer" + }, + { + "name": "Florent Morselli", + "email": "florent.morselli@spomky-labs.com", + "role": "Spomky-Labs PKI Framework developer" } ], - "description": "A developer friendly wrapper around Fractal", - "homepage": "https://github.com/spatie/fractalistic", + "description": "A PHP framework for managing Public Key Infrastructures. It comprises X.509 public key certificates, attribute certificates, certification requests and certification path validation.", + "homepage": "https://github.com/spomky-labs/pki-framework", "keywords": [ - "api", - "fractal", - "fractalistic", - "spatie", - "transform" + "DER", + "Private Key", + "ac", + "algorithm identifier", + "asn.1", + "asn1", + "attribute certificate", + "certificate", + "certification request", + "cryptography", + "csr", + "decrypt", + "ec", + "encrypt", + "pem", + "pkcs", + "public key", + "rsa", + "sign", + "signature", + "verify", + "x.509", + "x.690", + "x509", + "x690" ], "support": { - "issues": "https://github.com/spatie/fractalistic/issues", - "source": "https://github.com/spatie/fractalistic/tree/2.11.0" + "issues": "https://github.com/Spomky-Labs/pki-framework/issues", + "source": "https://github.com/Spomky-Labs/pki-framework/tree/1.4.2" }, "funding": [ { - "url": "https://github.com/spatie", + "url": "https://github.com/Spomky", "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" } ], - "time": "2025-01-27T09:52:33+00:00" + "time": "2026-03-23T22:56:56+00:00" }, { - "name": "spatie/laravel-data", - "version": "4.15.2", + "name": "staudenmeir/eloquent-has-many-deep", + "version": "v1.21.3", "source": { "type": "git", - "url": "https://github.com/spatie/laravel-data.git", - "reference": "50f5abe716ff1ad9a3e96dcfdeb4ad00f014bf8d" + "url": "https://github.com/staudenmeir/eloquent-has-many-deep.git", + "reference": "627986482120e1d5787167bdeb953afa0835bc5d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-data/zipball/50f5abe716ff1ad9a3e96dcfdeb4ad00f014bf8d", - "reference": "50f5abe716ff1ad9a3e96dcfdeb4ad00f014bf8d", + "url": "https://api.github.com/repos/staudenmeir/eloquent-has-many-deep/zipball/627986482120e1d5787167bdeb953afa0835bc5d", + "reference": "627986482120e1d5787167bdeb953afa0835bc5d", "shasum": "" }, "require": { - "illuminate/contracts": "^10.0|^11.0|^12.0", - "php": "^8.1", - "phpdocumentor/reflection": "^6.0", - "spatie/laravel-package-tools": "^1.9.0", - "spatie/php-structure-discoverer": "^2.0" + "illuminate/database": "^12.0", + "php": "^8.2", + "staudenmeir/eloquent-has-many-deep-contracts": "^1.3" }, "require-dev": { - "fakerphp/faker": "^1.14", - "friendsofphp/php-cs-fixer": "^3.0", - "inertiajs/inertia-laravel": "^2.0", - "livewire/livewire": "^3.0", + "awobaz/compoships": "^2.3", + "barryvdh/laravel-ide-helper": "^3.0", + "korridor/laravel-has-many-merged": "^1.2", + "larastan/larastan": "^3.0", + "laravel/framework": "^12.0", "mockery/mockery": "^1.6", - "nesbot/carbon": "^2.63|^3.0", - "orchestra/testbench": "^8.0|^9.0|^10.0", - "pestphp/pest": "^2.31|^3.0", - "pestphp/pest-plugin-laravel": "^2.0|^3.0", - "pestphp/pest-plugin-livewire": "^2.1|^3.0", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpunit/phpunit": "^10.0|^11.0|^12.0", - "spatie/invade": "^1.0", - "spatie/laravel-typescript-transformer": "^2.5", - "spatie/pest-plugin-snapshots": "^2.1", - "spatie/test-time": "^1.2" + "orchestra/testbench-core": "^10.0", + "phpunit/phpunit": "^11.0", + "staudenmeir/eloquent-json-relations": "^1.14", + "staudenmeir/laravel-adjacency-list": "^1.24" }, "type": "library", "extra": { "laravel": { "providers": [ - "Spatie\\LaravelData\\LaravelDataServiceProvider" + "Staudenmeir\\EloquentHasManyDeep\\IdeHelperServiceProvider" ] } }, "autoload": { "psr-4": { - "Spatie\\LaravelData\\": "src/" + "Staudenmeir\\EloquentHasManyDeep\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -5658,76 +5906,96 @@ ], "authors": [ { - "name": "Ruben Van Assche", - "email": "ruben@spatie.be", - "role": "Developer" + "name": "Jonas Staudenmeir", + "email": "mail@jonas-staudenmeir.de" } ], - "description": "Create unified resources and data transfer objects", - "homepage": "https://github.com/spatie/laravel-data", - "keywords": [ - "laravel", - "laravel-data", - "spatie" - ], + "description": "Laravel Eloquent HasManyThrough relationships with unlimited levels", "support": { - "issues": "https://github.com/spatie/laravel-data/issues", - "source": "https://github.com/spatie/laravel-data/tree/4.15.2" + "issues": "https://github.com/staudenmeir/eloquent-has-many-deep/issues", + "source": "https://github.com/staudenmeir/eloquent-has-many-deep/tree/v1.21.3" }, "funding": [ { - "url": "https://github.com/spatie", - "type": "github" + "url": "https://paypal.me/JonasStaudenmeir", + "type": "custom" } ], - "time": "2025-06-12T09:42:08+00:00" + "time": "2026-03-14T10:49:35+00:00" }, { - "name": "spatie/laravel-fractal", - "version": "6.3.2", + "name": "staudenmeir/eloquent-has-many-deep-contracts", + "version": "v1.3", "source": { "type": "git", - "url": "https://github.com/spatie/laravel-fractal.git", - "reference": "d078aa670233100e1309a0a7096c42f5b605ef29" + "url": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts.git", + "reference": "37ce351e4db919b3af606bc8ca0e62e2e4939cde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-fractal/zipball/d078aa670233100e1309a0a7096c42f5b605ef29", - "reference": "d078aa670233100e1309a0a7096c42f5b605ef29", + "url": "https://api.github.com/repos/staudenmeir/eloquent-has-many-deep-contracts/zipball/37ce351e4db919b3af606bc8ca0e62e2e4939cde", + "reference": "37ce351e4db919b3af606bc8ca0e62e2e4939cde", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0", - "league/fractal": "^0.20.1|^0.20", - "nesbot/carbon": "^2.63|^3.0", - "php": "^8.0", - "spatie/fractalistic": "^2.9.5|^2.9", - "spatie/laravel-package-tools": "^1.11" - }, - "require-dev": { - "ext-json": "*", - "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", - "pestphp/pest": "^1.22|^2.34|^3.0" + "illuminate/database": "^12.0", + "php": "^8.2" }, "type": "library", - "extra": { - "laravel": { - "aliases": { - "Fractal": "Spatie\\Fractal\\Facades\\Fractal" - }, - "providers": [ - "Spatie\\Fractal\\FractalServiceProvider" - ] + "autoload": { + "psr-4": { + "Staudenmeir\\EloquentHasManyDeepContracts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonas Staudenmeir", + "email": "mail@jonas-staudenmeir.de" } + ], + "description": "Contracts for staudenmeir/eloquent-has-many-deep", + "support": { + "issues": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts/issues", + "source": "https://github.com/staudenmeir/eloquent-has-many-deep-contracts/tree/v1.3" + }, + "time": "2025-02-15T17:11:01+00:00" + }, + { + "name": "symfony/clock", + "version": "v8.0.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/b55a638b189a6faa875e0ccdb00908fb87af95b3", + "reference": "b55a638b189a6faa875e0ccdb00908fb87af95b3", + "shasum": "" }, + "require": { + "php": ">=8.4", + "psr/clock": "^1.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", "autoload": { "files": [ - "src/helpers.php" + "Resources/now.php" ], "psr-4": { - "Spatie\\Fractal\\": "src" - } + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5735,65 +6003,96 @@ ], "authors": [ { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "An easy to use Fractal integration for Laravel applications", - "homepage": "https://github.com/spatie/laravel-fractal", + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", "keywords": [ - "api", - "fractal", - "laravel", - "laravel-fractal", - "lumen", - "spatie", - "transform" + "clock", + "psr20", + "time" ], "support": { - "source": "https://github.com/spatie/laravel-fractal/tree/6.3.2" + "source": "https://github.com/symfony/clock/tree/v8.0.8" }, "funding": [ { - "url": "https://spatie.be/open-source/support-us", + "url": "https://symfony.com/sponsor", "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2025-02-14T10:43:50+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "spatie/laravel-package-tools", - "version": "1.92.4", + "name": "symfony/console", + "version": "v7.4.13", "source": { "type": "git", - "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "d20b1969f836d210459b78683d85c9cd5c5f508c" + "url": "https://github.com/symfony/console.git", + "reference": "85095d2573eaefaf35e40b9513a9bf09f72cd217" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/d20b1969f836d210459b78683d85c9cd5c5f508c", - "reference": "d20b1969f836d210459b78683d85c9cd5c5f508c", + "url": "https://api.github.com/repos/symfony/console/zipball/85095d2573eaefaf35e40b9513a9bf09f72cd217", + "reference": "85095d2573eaefaf35e40b9513a9bf09f72cd217", "shasum": "" }, "require": { - "illuminate/contracts": "^9.28|^10.0|^11.0|^12.0", - "php": "^8.0" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2|^8.0" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "mockery/mockery": "^1.5", - "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0", - "pestphp/pest": "^1.23|^2.1|^3.1", - "phpunit/php-code-coverage": "^9.0|^10.0|^11.0", - "phpunit/phpunit": "^9.5.24|^10.5|^11.5", - "spatie/pest-plugin-test-time": "^1.1|^2.2" + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { "psr-4": { - "Spatie\\LaravelPackageTools\\": "src" - } + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5801,71 +6100,70 @@ ], "authors": [ { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "role": "Developer" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Tools for creating Laravel packages", - "homepage": "https://github.com/spatie/laravel-package-tools", + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", "keywords": [ - "laravel-package-tools", - "spatie" + "cli", + "command-line", + "console", + "terminal" ], "support": { - "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.92.4" + "source": "https://github.com/symfony/console/tree/v7.4.13" }, "funding": [ { - "url": "https://github.com/spatie", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2025-04-11T15:27:14+00:00" + "time": "2026-05-24T08:56:14+00:00" }, { - "name": "spatie/laravel-query-builder", - "version": "5.8.1", + "name": "symfony/css-selector", + "version": "v8.0.9", "source": { "type": "git", - "url": "https://github.com/spatie/laravel-query-builder.git", - "reference": "caa8467fa9e127ba7ea9e0aac93c71324365bae2" + "url": "https://github.com/symfony/css-selector.git", + "reference": "3665cfade90565430909b906394c73c8739e57d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-query-builder/zipball/caa8467fa9e127ba7ea9e0aac93c71324365bae2", - "reference": "caa8467fa9e127ba7ea9e0aac93c71324365bae2", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/3665cfade90565430909b906394c73c8739e57d0", + "reference": "3665cfade90565430909b906394c73c8739e57d0", "shasum": "" }, "require": { - "illuminate/database": "^10.0|^11.0", - "illuminate/http": "^10.0|^11.0", - "illuminate/support": "^10.0|^11.0", - "php": "^8.2", - "spatie/laravel-package-tools": "^1.11" - }, - "require-dev": { - "ext-json": "*", - "mockery/mockery": "^1.4", - "orchestra/testbench": "^7.0|^8.0", - "pestphp/pest": "^2.0", - "spatie/invade": "^2.0", - "spatie/laravel-ray": "^1.28" + "php": ">=8.4" }, "type": "library", - "extra": { - "laravel": { - "providers": [ - "Spatie\\QueryBuilder\\QueryBuilderServiceProvider" - ] - } - }, "autoload": { "psr-4": { - "Spatie\\QueryBuilder\\": "src", - "Spatie\\QueryBuilder\\Database\\Factories\\": "database/factories" - } + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5873,77 +6171,74 @@ ], "authors": [ { - "name": "Alex Vanderbist", - "email": "alex@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Easily build Eloquent queries from API requests", - "homepage": "https://github.com/spatie/laravel-query-builder", - "keywords": [ - "laravel-query-builder", - "spatie" - ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/spatie/laravel-query-builder/issues", - "source": "https://github.com/spatie/laravel-query-builder" + "source": "https://github.com/symfony/css-selector/tree/v8.0.9" }, "funding": [ { - "url": "https://spatie.be/open-source/support-us", + "url": "https://symfony.com/sponsor", "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2024-05-10T08:19:35+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { - "name": "spatie/php-structure-discoverer", - "version": "2.3.1", + "name": "symfony/deprecation-contracts", + "version": "v3.7.0", "source": { "type": "git", - "url": "https://github.com/spatie/php-structure-discoverer.git", - "reference": "42f4d731d3dd4b3b85732e05a8c1928fcfa2f4bc" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/42f4d731d3dd4b3b85732e05a8c1928fcfa2f4bc", - "reference": "42f4d731d3dd4b3b85732e05a8c1928fcfa2f4bc", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", + "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", "shasum": "" }, "require": { - "amphp/amp": "^v3.0", - "amphp/parallel": "^2.2", - "illuminate/collections": "^10.0|^11.0|^12.0", - "php": "^8.1", - "spatie/laravel-package-tools": "^1.4.3", - "symfony/finder": "^6.0|^7.0" - }, - "require-dev": { - "illuminate/console": "^10.0|^11.0|^12.0", - "laravel/pint": "^1.0", - "nunomaduro/collision": "^7.0|^8.0", - "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", - "pestphp/pest": "^2.0|^3.0", - "pestphp/pest-plugin-laravel": "^2.0|^3.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5|^10.0|^11.5.3", - "spatie/laravel-ray": "^1.26" + "php": ">=8.1" }, "type": "library", "extra": { - "laravel": { - "providers": [ - "Spatie\\StructureDiscoverer\\StructureDiscovererServiceProvider" - ] + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" } }, "autoload": { - "psr-4": { - "Spatie\\StructureDiscoverer\\": "src" - } + "files": [ + "function.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5951,60 +6246,77 @@ ], "authors": [ { - "name": "Ruben Van Assche", - "email": "ruben@spatie.be", - "role": "Developer" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Automatically discover structures within your PHP application", - "homepage": "https://github.com/spatie/php-structure-discoverer", - "keywords": [ - "discover", - "laravel", - "php", - "php-structure-discoverer" - ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", "support": { - "issues": "https://github.com/spatie/php-structure-discoverer/issues", - "source": "https://github.com/spatie/php-structure-discoverer/tree/2.3.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" }, "funding": [ { - "url": "https://github.com/LaravelAutoDiscoverer", + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "time": "2025-02-14T10:18:38+00:00" + "time": "2026-04-13T15:52:40+00:00" }, { - "name": "symfony/clock", + "name": "symfony/error-handler", "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/clock.git", - "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111" + "url": "https://github.com/symfony/error-handler.git", + "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/674fa3b98e21531dd040e613479f5f6fa8f32111", - "reference": "674fa3b98e21531dd040e613479f5f6fa8f32111", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", + "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", "shasum": "" }, "require": { "php": ">=8.2", - "psr/clock": "^1.0", - "symfony/polyfill-php83": "^1.28" + "psr/log": "^1|^2|^3", + "symfony/polyfill-php85": "^1.32", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, - "provide": { - "psr/clock-implementation": "1.0" + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/webpack-encore-bundle": "^1.0|^2.0" }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], "type": "library", "autoload": { - "files": [ - "Resources/now.php" - ], "psr-4": { - "Symfony\\Component\\Clock\\": "" + "Symfony\\Component\\ErrorHandler\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6016,23 +6328,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Decouples applications from the system clock", + "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", - "keywords": [ - "clock", - "psr20", - "time" - ], "support": { - "source": "https://github.com/symfony/clock/tree/v7.4.8" + "source": "https://github.com/symfony/error-handler/tree/v7.4.8" }, "funding": [ { @@ -6055,53 +6362,46 @@ "time": "2026-03-24T13:12:05+00:00" }, { - "name": "symfony/console", - "version": "v7.3.10", + "name": "symfony/event-dispatcher", + "version": "v8.0.9", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "a28c3e5b4df406e8fae8e9b18c40557b5dfc430c" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a28c3e5b4df406e8fae8e9b18c40557b5dfc430c", - "reference": "a28c3e5b4df406e8fae8e9b18c40557b5dfc430c", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/0c3c1a17604c4dbbec4b93fe162c538482096e1f", + "reference": "0c3c1a17604c4dbbec4b93fe162c538482096e1f", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^7.2" + "php": ">=8.4", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<6.4", - "symfony/dotenv": "<6.4", - "symfony/event-dispatcher": "<6.4", - "symfony/lock": "<6.4", - "symfony/process": "<6.4" + "symfony/security-http": "<7.4", + "symfony/service-contracts": "<2.5" }, "provide": { - "psr/log-implementation": "1.0|2.0|3.0" + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/event-dispatcher": "^6.4|^7.0", - "symfony/http-foundation": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/lock": "^6.4|^7.0", - "symfony/messenger": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/stopwatch": "^6.4|^7.0", - "symfony/var-dumper": "^6.4|^7.0" + "symfony/config": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/expression-language": "^7.4|^8.0", + "symfony/framework-bundle": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^7.4|^8.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Console\\": "" + "Symfony\\Component\\EventDispatcher\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6121,16 +6421,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Eases the creation of beautiful and testable command line interfaces", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", - "keywords": [ - "cli", - "command-line", - "console", - "terminal" - ], "support": { - "source": "https://github.com/symfony/console/tree/v7.3.10" + "source": "https://github.com/symfony/event-dispatcher/tree/v8.0.9" }, "funding": [ { @@ -6150,33 +6444,40 @@ "type": "tidelift" } ], - "time": "2026-01-13T10:52:14+00:00" + "time": "2026-04-18T13:51:42+00:00" }, { - "name": "symfony/css-selector", - "version": "v7.4.9", + "name": "symfony/event-dispatcher-contracts", + "version": "v3.7.0", "source": { "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "b75663ed96cf4756e28e3105476f220f92886cc4" + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4", - "reference": "b75663ed96cf4756e28e3105476f220f92886cc4", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32", + "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.1", + "psr/event-dispatcher": "^1" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, "autoload": { "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Contracts\\EventDispatcher\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6184,22 +6485,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Converts CSS selectors to XPath expressions", + "description": "Generic abstractions related to dispatching event", "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.4.9" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.0" }, "funding": [ { @@ -6219,38 +6524,35 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:18:21+00:00" + "time": "2026-01-05T13:30:16+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "v3.7.0", + "name": "symfony/finder", + "version": "v7.4.8", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b" + "url": "https://github.com/symfony/finder.git", + "reference": "e0be088d22278583a82da281886e8c3592fbf149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/50f59d1f3ca46d41ac911f97a78626b6756af35b", - "reference": "50f59d1f3ca46d41ac911f97a78626b6756af35b", + "url": "https://api.github.com/repos/symfony/finder/zipball/e0be088d22278583a82da281886e8c3592fbf149", + "reference": "e0be088d22278583a82da281886e8c3592fbf149", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.7-dev" - } + "require-dev": { + "symfony/filesystem": "^6.4|^7.0|^8.0" }, + "type": "library", "autoload": { - "files": [ - "function.php" + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6259,18 +6561,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "A generic function and convention to trigger deprecation notices", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/finder/tree/v7.4.8" }, "funding": [ { @@ -6290,46 +6592,46 @@ "type": "tidelift" } ], - "time": "2026-04-13T15:52:40+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { - "name": "symfony/error-handler", - "version": "v7.4.8", + "name": "symfony/http-foundation", + "version": "v7.4.13", "source": { "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa" + "url": "https://github.com/symfony/http-foundation.git", + "reference": "bc354f47c62301e990b7874fa662326368508e2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", - "reference": "8dd79d8af777ee6cba2fd4d98da6ffb839f3c0fa", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/bc354f47c62301e990b7874fa662326368508e2c", + "reference": "bc354f47c62301e990b7874fa662326368508e2c", "shasum": "" }, "require": { "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/polyfill-php85": "^1.32", - "symfony/var-dumper": "^6.4|^7.0|^8.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "^1.1" }, "conflict": { - "symfony/deprecation-contracts": "<2.5", - "symfony/http-kernel": "<6.4" + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" }, "require-dev": { - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/deprecation-contracts": "^2.5|^3", + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5|^8.0", + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/serializer": "^6.4|^7.0|^8.0", - "symfony/webpack-encore-bundle": "^1.0|^2.0" + "symfony/mime": "^6.4|^7.0|^8.0", + "symfony/rate-limiter": "^6.4|^7.0|^8.0" }, - "bin": [ - "Resources/bin/patch-type-declarations" - ], "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\ErrorHandler\\": "" + "Symfony\\Component\\HttpFoundation\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6349,10 +6651,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides tools to manage errors and ease debugging PHP code", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.4.8" + "source": "https://github.com/symfony/http-foundation/tree/v7.4.13" }, "funding": [ { @@ -6372,49 +6674,83 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-24T11:20:33+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v7.4.9", + "name": "symfony/http-kernel", + "version": "v7.4.13", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101" + "url": "https://github.com/symfony/http-kernel.git", + "reference": "9df847980c436451f4f51d1284491bb4356dd989" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e4a2e29753c7801f7a8340e066cfa788f3bc8101", - "reference": "e4a2e29753c7801f7a8340e066cfa788f3bc8101", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9df847980c436451f4f51d1284491bb4356dd989", + "reference": "9df847980c436451f4f51d1284491bb4356dd989", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/event-dispatcher-contracts": "^2.5|^3" + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^7.3|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", "symfony/dependency-injection": "<6.4", - "symfony/service-contracts": "<2.5" + "symfony/doctrine-bridge": "<6.4", + "symfony/flex": "<2.10", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" }, "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0|3.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "^1|^2|^3", + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0|^8.0", + "symfony/clock": "^6.4|^7.0|^8.0", "symfony/config": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/css-selector": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4.1|^7.0.1|^8.0", + "symfony/dom-crawler": "^6.4|^7.0|^8.0", "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/framework-bundle": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0|^8.0" + "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/property-access": "^7.1|^8.0", + "symfony/routing": "^6.4|^7.0|^8.0", + "symfony/serializer": "^7.1|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/translation": "^6.4|^7.0|^8.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0|^8.0", + "symfony/validator": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0", + "symfony/var-exporter": "^6.4|^7.0|^8.0", + "twig/twig": "^3.12" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" + "Symfony\\Component\\HttpKernel\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6434,10 +6770,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.9" + "source": "https://github.com/symfony/http-kernel/tree/v7.4.13" }, "funding": [ { @@ -6457,40 +6793,52 @@ "type": "tidelift" } ], - "time": "2026-04-18T13:18:21+00:00" + "time": "2026-05-27T08:31:43+00:00" }, { - "name": "symfony/event-dispatcher-contracts", - "version": "v3.7.0", + "name": "symfony/mailer", + "version": "v7.4.12", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32" + "url": "https://github.com/symfony/mailer.git", + "reference": "5cefb712a25f320579615ba9e1942abaeade7dff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/ccba7060602b7fed0b03c85bf025257f76d9ef32", - "reference": "ccba7060602b7fed0b03c85bf025257f76d9ef32", + "url": "https://api.github.com/repos/symfony/mailer/zipball/5cefb712a25f320579615ba9e1942abaeade7dff", + "reference": "5cefb712a25f320579615ba9e1942abaeade7dff", "shasum": "" }, "require": { - "php": ">=8.1", - "psr/event-dispatcher": "^1" + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/mime": "^7.2|^8.0", + "symfony/service-contracts": "^2.5|^3" }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/contracts", - "name": "symfony/contracts" - }, - "branch-alias": { - "dev-main": "3.7-dev" - } + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0|^8.0", + "symfony/http-client": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/twig-bridge": "^6.4|^7.0|^8.0" }, + "type": "library", "autoload": { "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" - } + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6498,26 +6846,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to dispatching event", + "description": "Helps sending emails", "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.0" + "source": "https://github.com/symfony/mailer/tree/v7.4.12" }, "funding": [ { @@ -6537,32 +6877,49 @@ "type": "tidelift" } ], - "time": "2026-01-05T13:30:16+00:00" + "time": "2026-05-20T07:20:23+00:00" }, { - "name": "symfony/finder", - "version": "v7.4.8", + "name": "symfony/mime", + "version": "v7.4.13", "source": { "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "e0be088d22278583a82da281886e8c3592fbf149" + "url": "https://github.com/symfony/mime.git", + "reference": "a845722765c4f6b2ce88beaf4f4479975b186770" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e0be088d22278583a82da281886e8c3592fbf149", - "reference": "e0be088d22278583a82da281886e8c3592fbf149", + "url": "https://api.github.com/repos/symfony/mime/zipball/a845722765c4f6b2ce88beaf4f4479975b186770", + "reference": "a845722765c4f6b2ce88beaf4f4479975b186770", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" }, "require-dev": { - "symfony/filesystem": "^6.4|^7.0|^8.0" + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4.3|^7.0.3|^8.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Finder\\": "" + "Symfony\\Component\\Mime\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6582,10 +6939,14 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Finds files and directories via an intuitive fluent interface", + "description": "Allows manipulating MIME messages", "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], "support": { - "source": "https://github.com/symfony/finder/tree/v7.4.8" + "source": "https://github.com/symfony/mime/tree/v7.4.13" }, "funding": [ { @@ -6605,50 +6966,45 @@ "type": "tidelift" } ], - "time": "2026-03-24T13:12:05+00:00" + "time": "2026-05-23T16:22:37+00:00" }, { - "name": "symfony/http-foundation", - "version": "v7.4.13", + "name": "symfony/polyfill-ctype", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "bc354f47c62301e990b7874fa662326368508e2c" + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/bc354f47c62301e990b7874fa662326368508e2c", - "reference": "bc354f47c62301e990b7874fa662326368508e2c", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "^1.1" + "php": ">=7.2" }, - "conflict": { - "doctrine/dbal": "<3.6", - "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + "provide": { + "ext-ctype": "*" }, - "require-dev": { - "doctrine/dbal": "^3.6|^4", - "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.4.12|^7.1.5|^8.0", - "symfony/clock": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/mime": "^6.4|^7.0|^8.0", - "symfony/rate-limiter": "^6.4|^7.0|^8.0" + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6656,18 +7012,24 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Defines an object-oriented layer for the HTTP specification", + "description": "Symfony polyfill for ctype functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.4.13" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -6687,106 +7049,69 @@ "type": "tidelift" } ], - "time": "2026-05-24T11:20:33+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "symfony/http-kernel", - "version": "v7.4.13", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "9df847980c436451f4f51d1284491bb4356dd989" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "e9247d281d694a5120554d9afaf54e070e88a603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9df847980c436451f4f51d1284491bb4356dd989", - "reference": "9df847980c436451f4f51d1284491bb4356dd989", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", + "reference": "e9247d281d694a5120554d9afaf54e070e88a603", "shasum": "" }, "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0|^8.0", - "symfony/event-dispatcher": "^7.3|^8.0", - "symfony/http-foundation": "^7.4|^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/browser-kit": "<6.4", - "symfony/cache": "<6.4", - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/doctrine-bridge": "<6.4", - "symfony/flex": "<2.10", - "symfony/form": "<6.4", - "symfony/http-client": "<6.4", - "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<6.4", - "symfony/messenger": "<6.4", - "symfony/translation": "<6.4", - "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<6.4", - "symfony/validator": "<6.4", - "symfony/var-dumper": "<6.4", - "twig/twig": "<3.12" - }, - "provide": { - "psr/log-implementation": "1.0|2.0|3.0" + "php": ">=7.2" }, - "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^6.4|^7.0|^8.0", - "symfony/clock": "^6.4|^7.0|^8.0", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/css-selector": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4.1|^7.0.1|^8.0", - "symfony/dom-crawler": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/finder": "^6.4|^7.0|^8.0", - "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/property-access": "^7.1|^8.0", - "symfony/routing": "^6.4|^7.0|^8.0", - "symfony/serializer": "^7.1|^8.0", - "symfony/stopwatch": "^6.4|^7.0|^8.0", - "symfony/translation": "^6.4|^7.0|^8.0", - "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^6.4|^7.0|^8.0", - "symfony/validator": "^6.4|^7.0|^8.0", - "symfony/var-dumper": "^6.4|^7.0|^8.0", - "symfony/var-exporter": "^6.4|^7.0|^8.0", - "twig/twig": "^3.12" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a structured process for converting a Request into a Response", + "description": "Symfony polyfill for intl's grapheme_* functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.4.13" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" }, "funding": [ { @@ -6806,52 +7131,43 @@ "type": "tidelift" } ], - "time": "2026-05-27T08:31:43+00:00" + "time": "2026-05-26T05:58:03+00:00" }, { - "name": "symfony/mailer", - "version": "v7.4.12", + "name": "symfony/polyfill-intl-idn", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/mailer.git", - "reference": "5cefb712a25f320579615ba9e1942abaeade7dff" + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "dc21118016c039a66235cf93d96b435ffb282412" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/5cefb712a25f320579615ba9e1942abaeade7dff", - "reference": "5cefb712a25f320579615ba9e1942abaeade7dff", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412", + "reference": "dc21118016c039a66235cf93d96b435ffb282412", "shasum": "" }, "require": { - "egulias/email-validator": "^2.1.10|^3|^4", - "php": ">=8.2", - "psr/event-dispatcher": "^1", - "psr/log": "^1|^2|^3", - "symfony/event-dispatcher": "^6.4|^7.0|^8.0", - "symfony/mime": "^7.2|^8.0", - "symfony/service-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<6.4", - "symfony/messenger": "<6.4", - "symfony/mime": "<6.4", - "symfony/twig-bridge": "<6.4" + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" }, - "require-dev": { - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/http-client": "^6.4|^7.0|^8.0", - "symfony/messenger": "^6.4|^7.0|^8.0", - "symfony/twig-bridge": "^6.4|^7.0|^8.0" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Mailer\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6859,18 +7175,30 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Helps sending emails", + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/mailer/tree/v7.4.12" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1" }, "funding": [ { @@ -6890,52 +7218,44 @@ "type": "tidelift" } ], - "time": "2026-05-20T07:20:23+00:00" + "time": "2026-05-25T15:22:23+00:00" }, { - "name": "symfony/mime", - "version": "v7.4.13", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.38.0", "source": { "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "a845722765c4f6b2ce88beaf4f4479975b186770" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/a845722765c4f6b2ce88beaf4f4479975b186770", - "reference": "a845722765c4f6b2ce88beaf4f4479975b186770", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b", + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0" - }, - "conflict": { - "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<5.2|>=7", - "phpdocumentor/type-resolver": "<1.5.1", - "symfony/mailer": "<6.4", - "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + "php": ">=7.2" }, - "require-dev": { - "egulias/email-validator": "^2.1.10|^3.1|^4", - "league/html-to-markdown": "^5.0", - "phpdocumentor/reflection-docblock": "^5.2|^6.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/property-access": "^6.4|^7.0|^8.0", - "symfony/property-info": "^6.4|^7.0|^8.0", - "symfony/serializer": "^6.4.3|^7.0.3|^8.0" + "suggest": { + "ext-intl": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Mime\\": "" + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6944,22 +7264,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Allows manipulating MIME messages", + "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", "keywords": [ - "mime", - "mime-type" + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.4.13" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0" }, "funding": [ { @@ -6979,30 +7303,31 @@ "type": "tidelift" } ], - "time": "2026-05-23T16:22:37+00:00" + "time": "2026-05-25T13:48:31+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.37.0", + "name": "symfony/polyfill-mbstring", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "141046a8f9477948ff284fa65be2095baafb94f2" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", - "reference": "141046a8f9477948ff284fa65be2095baafb94f2", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/14c5439eec4ccff081ac14eca2dc57feb2a66d92", + "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92", "shasum": "" }, "require": { + "ext-iconv": "*", "php": ">=7.2" }, "provide": { - "ext-ctype": "*" + "ext-mbstring": "*" }, "suggest": { - "ext-ctype": "For best performance" + "ext-mbstring": "For best performance" }, "type": "library", "extra": { @@ -7016,7 +7341,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" + "Symfony\\Polyfill\\Mbstring\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -7025,24 +7350,25 @@ ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for ctype functions", + "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "ctype", + "mbstring", "polyfill", - "portable" + "portable", + "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.1" }, "funding": [ { @@ -7062,28 +7388,25 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:19:22+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.38.1", + "name": "symfony/polyfill-php80", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "e9247d281d694a5120554d9afaf54e070e88a603" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", - "reference": "e9247d281d694a5120554d9afaf54e070e88a603", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { "php": ">=7.2" }, - "suggest": { - "ext-intl": "For best performance" - }, "type": "library", "extra": { "thanks": { @@ -7096,14 +7419,21 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - } + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -7113,18 +7443,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's grapheme_* functions", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "grapheme", - "intl", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -7144,28 +7472,24 @@ "type": "tidelift" } ], - "time": "2026-05-26T05:58:03+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "symfony/polyfill-intl-idn", + "name": "symfony/polyfill-php83", "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "dc21118016c039a66235cf93d96b435ffb282412" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "8339098cae28673c15cce00d80734af0453054e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/dc21118016c039a66235cf93d96b435ffb282412", - "reference": "dc21118016c039a66235cf93d96b435ffb282412", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", + "reference": "8339098cae28673c15cce00d80734af0453054e2", "shasum": "" }, "require": { - "php": ">=7.2", - "symfony/polyfill-intl-normalizer": "^1.10" - }, - "suggest": { - "ext-intl": "For best performance" + "php": ">=7.2" }, "type": "library", "extra": { @@ -7179,8 +7503,11 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Idn\\": "" - } + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7188,30 +7515,24 @@ ], "authors": [ { - "name": "Laurent Bassin", - "email": "laurent@bassin.info" - }, - { - "name": "Trevor Rowbotham", - "email": "trevor.rowbotham@pm.me" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "idn", - "intl", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" }, "funding": [ { @@ -7231,28 +7552,25 @@ "type": "tidelift" } ], - "time": "2026-05-25T15:22:23+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.38.0", + "name": "symfony/polyfill-php84", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b" + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b", - "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { "php": ">=7.2" }, - "suggest": { - "ext-intl": "For best performance" - }, "type": "library", "extra": { "thanks": { @@ -7265,7 +7583,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + "Symfony\\Polyfill\\Php84\\": "" }, "classmap": [ "Resources/stubs" @@ -7285,18 +7603,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "intl", - "normalizer", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -7316,32 +7632,25 @@ "type": "tidelift" } ], - "time": "2026-05-25T13:48:31+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { - "name": "symfony/polyfill-mbstring", + "name": "symfony/polyfill-php85", "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92" + "url": "https://github.com/symfony/polyfill-php85.git", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/14c5439eec4ccff081ac14eca2dc57feb2a66d92", - "reference": "14c5439eec4ccff081ac14eca2dc57feb2a66d92", + "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", "shasum": "" }, "require": { - "ext-iconv": "*", "php": ">=7.2" }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, "type": "library", "extra": { "thanks": { @@ -7354,8 +7663,11 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } + "Symfony\\Polyfill\\Php85\\": "" + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7371,17 +7683,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", - "mbstring", "polyfill", "portable", "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.1" + "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" }, "funding": [ { @@ -7401,25 +7712,31 @@ "type": "tidelift" } ], - "time": "2026-05-26T12:51:13+00:00" + "time": "2026-05-26T02:25:22+00:00" }, { - "name": "symfony/polyfill-php80", + "name": "symfony/polyfill-uuid", "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", - "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", "shasum": "" }, "require": { "php": ">=7.2" }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, "type": "library", "extra": { "thanks": { @@ -7432,11 +7749,8 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] + "Symfony\\Polyfill\\Uuid\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7444,28 +7758,24 @@ ], "authors": [ { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "description": "Symfony polyfill for uuid functions", "homepage": "https://symfony.com", "keywords": [ "compatibility", "polyfill", "portable", - "shim" + "uuid" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" }, "funding": [ { @@ -7488,38 +7798,29 @@ "time": "2026-04-10T16:19:22+00:00" }, { - "name": "symfony/polyfill-php83", - "version": "v1.38.1", + "name": "symfony/process", + "version": "v7.4.13", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "8339098cae28673c15cce00d80734af0453054e2" + "url": "https://github.com/symfony/process.git", + "reference": "f5804be144caceb570f6747519999636b664f24c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/8339098cae28673c15cce00d80734af0453054e2", - "reference": "8339098cae28673c15cce00d80734af0453054e2", + "url": "https://api.github.com/repos/symfony/process/zipball/f5804be144caceb570f6747519999636b664f24c", + "reference": "f5804be144caceb570f6747519999636b664f24c", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.2" }, "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php83\\": "" + "Symfony\\Component\\Process\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -7528,24 +7829,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.38.1" + "source": "https://github.com/symfony/process/tree/v7.4.13" }, "funding": [ { @@ -7565,41 +7860,37 @@ "type": "tidelift" } ], - "time": "2026-05-26T12:51:13+00:00" + "time": "2026-05-23T16:05:06+00:00" }, { - "name": "symfony/polyfill-php85", - "version": "v1.38.1", + "name": "symfony/property-access", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1" + "url": "https://github.com/symfony/property-access.git", + "reference": "704c7808116fcdd67327db7b17de56b8ef6169e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", - "reference": "ba2ba04f3352cfa2dcbbcb90aee13ed967f505b1", + "url": "https://api.github.com/repos/symfony/property-access/zipball/704c7808116fcdd67327db7b17de56b8ef6169e4", + "reference": "704c7808116fcdd67327db7b17de56b8ef6169e4", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.4", + "symfony/property-info": "^7.4.4|^8.0.4" }, - "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } + "require-dev": { + "symfony/cache": "^7.4|^8.0", + "symfony/var-exporter": "^7.4|^8.0" }, + "type": "library", "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Php85\\": "" + "Symfony\\Component\\PropertyAccess\\": "" }, - "classmap": [ - "Resources/stubs" + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -7608,24 +7899,29 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.5+ features to lower PHP versions", + "description": "Provides functions to read and write from/to an object or array using a simple string notation", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property-path", + "reflection" ], "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.38.1" + "source": "https://github.com/symfony/property-access/tree/v8.0.8" }, "funding": [ { @@ -7645,45 +7941,46 @@ "type": "tidelift" } ], - "time": "2026-05-26T02:25:22+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "symfony/polyfill-uuid", - "version": "v1.37.0", + "name": "symfony/property-info", + "version": "v8.0.8", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-uuid.git", - "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94" + "url": "https://github.com/symfony/property-info.git", + "reference": "c21711980653360d6ef5c26d0f9ca6f58a1135c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/26dfec253c4cf3e51b541b52ddf7e42cb0908e94", - "reference": "26dfec253c4cf3e51b541b52ddf7e42cb0908e94", + "url": "https://api.github.com/repos/symfony/property-info/zipball/c21711980653360d6ef5c26d0f9ca6f58a1135c6", + "reference": "c21711980653360d6ef5c26d0f9ca6f58a1135c6", "shasum": "" }, "require": { - "php": ">=7.2" + "php": ">=8.4", + "symfony/string": "^7.4|^8.0", + "symfony/type-info": "^7.4.7|^8.0.7" }, - "provide": { - "ext-uuid": "*" + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1" }, - "suggest": { - "ext-uuid": "For best performance" + "require-dev": { + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "symfony/cache": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0" }, "type": "library", - "extra": { - "thanks": { - "url": "https://github.com/symfony/polyfill", - "name": "symfony/polyfill" - } - }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Polyfill\\Uuid\\": "" - } + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -7691,24 +7988,26 @@ ], "authors": [ { - "name": "Grégoire Pineau", - "email": "lyrixx@lyrixx.info" + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for uuid functions", + "description": "Extracts information about PHP class' properties using metadata of popular sources", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "polyfill", - "portable", - "uuid" + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" ], "support": { - "source": "https://github.com/symfony/polyfill-uuid/tree/v1.37.0" + "source": "https://github.com/symfony/property-info/tree/v8.0.8" }, "funding": [ { @@ -7728,29 +8027,43 @@ "type": "tidelift" } ], - "time": "2026-04-10T16:19:22+00:00" + "time": "2026-03-30T15:14:47+00:00" }, { - "name": "symfony/process", + "name": "symfony/routing", "version": "v7.4.13", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "f5804be144caceb570f6747519999636b664f24c" + "url": "https://github.com/symfony/routing.git", + "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f5804be144caceb570f6747519999636b664f24c", - "reference": "f5804be144caceb570f6747519999636b664f24c", + "url": "https://api.github.com/repos/symfony/routing/zipball/3a162171bb008e5e0f15dce6581373a4c0e8390d", + "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/yaml": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Process\\": "" + "Symfony\\Component\\Routing\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -7770,10 +8083,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Executes commands in sub-processes", + "description": "Maps an HTTP request to a set of configuration variables", "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], "support": { - "source": "https://github.com/symfony/process/tree/v7.4.13" + "source": "https://github.com/symfony/routing/tree/v7.4.13" }, "funding": [ { @@ -7793,43 +8112,62 @@ "type": "tidelift" } ], - "time": "2026-05-23T16:05:06+00:00" + "time": "2026-05-24T11:20:33+00:00" }, { - "name": "symfony/routing", - "version": "v7.4.13", + "name": "symfony/serializer", + "version": "v8.0.10", "source": { "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d" + "url": "https://github.com/symfony/serializer.git", + "reference": "72ed7e1475790714f07c3a59bd01fd32cd022fdf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/3a162171bb008e5e0f15dce6581373a4c0e8390d", - "reference": "3a162171bb008e5e0f15dce6581373a4c0e8390d", + "url": "https://api.github.com/repos/symfony/serializer/zipball/72ed7e1475790714f07c3a59bd01fd32cd022fdf", + "reference": "72ed7e1475790714f07c3a59bd01fd32cd022fdf", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3" + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/config": "<6.4", - "symfony/dependency-injection": "<6.4", - "symfony/yaml": "<6.4" + "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/property-access": "<7.4.2|>=8.0,<8.0.2", + "symfony/property-info": "<7.4", + "symfony/type-info": "<7.4" }, "require-dev": { - "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", - "symfony/yaml": "^6.4|^7.0|^8.0" + "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", + "seld/jsonlint": "^1.10", + "symfony/cache": "^7.4|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/error-handler": "^7.4|^8.0", + "symfony/filesystem": "^7.4|^8.0", + "symfony/form": "^7.4|^8.0", + "symfony/http-foundation": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/messenger": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", + "symfony/property-access": "^7.4.2|^8.0.2", + "symfony/property-info": "^7.4|^8.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/type-info": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0", + "symfony/var-exporter": "^7.4|^8.0", + "symfony/yaml": "^7.4|^8.0" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\Routing\\": "" + "Symfony\\Component\\Serializer\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -7849,16 +8187,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Maps an HTTP request to a set of configuration variables", + "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", - "keywords": [ - "router", - "routing", - "uri", - "url" - ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.4.13" + "source": "https://github.com/symfony/serializer/tree/v8.0.10" }, "funding": [ { @@ -7878,7 +8210,7 @@ "type": "tidelift" } ], - "time": "2026-05-24T11:20:33+00:00" + "time": "2026-05-04T13:41:39+00:00" }, { "name": "symfony/service-contracts", @@ -7969,35 +8301,34 @@ }, { "name": "symfony/string", - "version": "v7.4.13", + "version": "v8.0.13", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "961683010db3b27ec6ebcd7308e6e1ee8fa7ffde" + "reference": "f2e3e4d33579350d1b12001ef2872f86b27ed3dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/961683010db3b27ec6ebcd7308e6e1ee8fa7ffde", - "reference": "961683010db3b27ec6ebcd7308e6e1ee8fa7ffde", + "url": "https://api.github.com/repos/symfony/string/zipball/f2e3e4d33579350d1b12001ef2872f86b27ed3dc", + "reference": "f2e3e4d33579350d1b12001ef2872f86b27ed3dc", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-intl-grapheme": "~1.33", - "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-intl-grapheme": "^1.33", + "symfony/polyfill-intl-normalizer": "^1.0", + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1|^8.0", - "symfony/http-client": "^6.4|^7.0|^8.0", - "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/emoji": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0|^8.0" + "symfony/var-exporter": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -8036,7 +8367,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.13" + "source": "https://github.com/symfony/string/tree/v8.0.13" }, "funding": [ { @@ -8056,38 +8387,31 @@ "type": "tidelift" } ], - "time": "2026-05-23T15:23:29+00:00" + "time": "2026-05-23T18:05:53+00:00" }, { "name": "symfony/translation", - "version": "v7.4.10", + "version": "v8.0.10", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "ada7578c30dd5feaa8259cff3e885069ea81ddde" + "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/ada7578c30dd5feaa8259cff3e885069ea81ddde", - "reference": "ada7578c30dd5feaa8259cff3e885069ea81ddde", + "url": "https://api.github.com/repos/symfony/translation/zipball/f63e9342e12646a57c91ef8a366a4f9d8e557b67", + "reference": "f63e9342e12646a57c91ef8a366a4f9d8e557b67", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^2.5.3|^3.3" + "php": ">=8.4", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation-contracts": "^3.6.1" }, "conflict": { "nikic/php-parser": "<5.0", - "symfony/config": "<6.4", - "symfony/console": "<6.4", - "symfony/dependency-injection": "<6.4", "symfony/http-client-contracts": "<2.5", - "symfony/http-kernel": "<6.4", - "symfony/service-contracts": "<2.5", - "symfony/twig-bundle": "<6.4", - "symfony/yaml": "<6.4" + "symfony/service-contracts": "<2.5" }, "provide": { "symfony/translation-implementation": "2.3|3.0" @@ -8095,17 +8419,17 @@ "require-dev": { "nikic/php-parser": "^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/finder": "^6.4|^7.0|^8.0", + "symfony/config": "^7.4|^8.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/finder": "^7.4|^8.0", "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/intl": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^6.4|^7.0|^8.0", + "symfony/routing": "^7.4|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^6.4|^7.0|^8.0" + "symfony/yaml": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -8136,7 +8460,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.4.10" + "source": "https://github.com/symfony/translation/tree/v8.0.10" }, "funding": [ { @@ -8156,7 +8480,7 @@ "type": "tidelift" } ], - "time": "2026-05-06T11:19:24+00:00" + "time": "2026-05-06T11:30:54+00:00" }, { "name": "symfony/translation-contracts", @@ -8240,6 +8564,88 @@ ], "time": "2026-01-05T13:30:16+00:00" }, + { + "name": "symfony/type-info", + "version": "v8.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/type-info.git", + "reference": "08723aceb8c3271e8cb3db8b2565728b0c88e866" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/type-info/zipball/08723aceb8c3271e8cb3db8b2565728b0c88e866", + "reference": "08723aceb8c3271e8cb3db8b2565728b0c88e866", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "phpstan/phpdoc-parser": "<1.30" + }, + "require-dev": { + "phpstan/phpdoc-parser": "^1.30|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\TypeInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Arlaud", + "email": "mathias.arlaud@gmail.com" + }, + { + "name": "Baptiste LEDUC", + "email": "baptiste.leduc@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts PHP types information.", + "homepage": "https://symfony.com", + "keywords": [ + "PHPStan", + "phpdoc", + "symfony", + "type" + ], + "support": { + "source": "https://github.com/symfony/type-info/tree/v8.0.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-29T15:02:55+00:00" + }, { "name": "symfony/uid", "version": "v7.4.9", @@ -8618,6 +9024,163 @@ ], "time": "2026-04-26T05:33:54+00:00" }, + { + "name": "web-auth/cose-lib", + "version": "4.5.2", + "source": { + "type": "git", + "url": "https://github.com/web-auth/cose-lib.git", + "reference": "5b38660f90070a8e45f3dbc9528ade3b608dd77d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-auth/cose-lib/zipball/5b38660f90070a8e45f3dbc9528ade3b608dd77d", + "reference": "5b38660f90070a8e45f3dbc9528ade3b608dd77d", + "shasum": "" + }, + "require": { + "brick/math": "^0.9|^0.10|^0.11|^0.12|^0.13|^0.14|^0.15|^0.16|^0.17", + "ext-json": "*", + "ext-openssl": "*", + "php": ">=8.1", + "spomky-labs/pki-framework": "^1.0" + }, + "require-dev": { + "spomky-labs/cbor-php": "^3.2.2" + }, + "suggest": { + "ext-bcmath": "For better performance, please install either GMP (recommended) or BCMath extension", + "ext-gmp": "For better performance, please install either GMP (recommended) or BCMath extension", + "spomky-labs/cbor-php": "For COSE Signature support" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cose\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-auth/cose/contributors" + } + ], + "description": "CBOR Object Signing and Encryption (COSE) For PHP", + "homepage": "https://github.com/web-auth", + "keywords": [ + "COSE", + "RFC8152" + ], + "support": { + "issues": "https://github.com/web-auth/cose-lib/issues", + "source": "https://github.com/web-auth/cose-lib/tree/4.5.2" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2026-05-03T09:49:50+00:00" + }, + { + "name": "web-auth/webauthn-lib", + "version": "5.3.4", + "source": { + "type": "git", + "url": "https://github.com/web-auth/webauthn-lib.git", + "reference": "dbb2d7a03db5893da2ef1f2898063ab8f7792838" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/web-auth/webauthn-lib/zipball/dbb2d7a03db5893da2ef1f2898063ab8f7792838", + "reference": "dbb2d7a03db5893da2ef1f2898063ab8f7792838", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "paragonie/constant_time_encoding": "^2.6|^3.0", + "php": ">=8.2", + "phpdocumentor/reflection-docblock": "^5.3|^6.0", + "psr/clock": "^1.0", + "psr/event-dispatcher": "^1.0", + "psr/log": "^1.0|^2.0|^3.0", + "spomky-labs/cbor-php": "^3.0", + "spomky-labs/pki-framework": "^1.0", + "symfony/clock": "^6.4|^7.0|^8.0", + "symfony/deprecation-contracts": "^3.2", + "symfony/property-access": "^6.4|^7.0|^8.0", + "symfony/property-info": "^6.4|^7.0|^8.0", + "symfony/serializer": "^6.4|^7.0|^8.0", + "symfony/uid": "^6.4|^7.0|^8.0", + "web-auth/cose-lib": "^4.2.3" + }, + "suggest": { + "psr/log-implementation": "Recommended to receive logs from the library", + "symfony/event-dispatcher": "Recommended to use dispatched events", + "web-token/jwt-library": "Mandatory for fetching Metadata Statement from distant sources" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/web-auth/webauthn-framework", + "name": "web-auth/webauthn-framework" + } + }, + "autoload": { + "psr-4": { + "Webauthn\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/web-auth/webauthn-library/contributors" + } + ], + "description": "FIDO2/Webauthn Support For PHP", + "homepage": "https://github.com/web-auth", + "keywords": [ + "FIDO2", + "fido", + "webauthn" + ], + "support": { + "source": "https://github.com/web-auth/webauthn-lib/tree/5.3.4" + }, + "funding": [ + { + "url": "https://github.com/Spomky", + "type": "github" + }, + { + "url": "https://www.patreon.com/FlorentMorselli", + "type": "patreon" + } + ], + "time": "2026-05-18T11:59:46+00:00" + }, { "name": "webmozart/assert", "version": "1.12.1", @@ -8680,16 +9243,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v7.4.9", + "version": "v7.8.5", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "633c0987ecf6d9b057431225da37b088aa9274a5" + "reference": "9b324c8fc319cf9728b581c7a90e1c8f6361c5e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/633c0987ecf6d9b057431225da37b088aa9274a5", - "reference": "633c0987ecf6d9b057431225da37b088aa9274a5", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/9b324c8fc319cf9728b581c7a90e1c8f6361c5e5", + "reference": "9b324c8fc319cf9728b581c7a90e1c8f6361c5e5", "shasum": "" }, "require": { @@ -8697,27 +9260,27 @@ "ext-pcre": "*", "ext-reflection": "*", "ext-simplexml": "*", - "fidry/cpu-core-counter": "^1.2.0", - "jean85/pretty-package-versions": "^2.0.6", - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-timer": "^6.0.0", - "phpunit/phpunit": "^10.5.47", - "sebastian/environment": "^6.1.0", - "symfony/console": "^6.4.7 || ^7.1.5", - "symfony/process": "^6.4.7 || ^7.1.5" + "fidry/cpu-core-counter": "^1.3.0", + "jean85/pretty-package-versions": "^2.1.1", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", + "phpunit/php-code-coverage": "^11.0.12", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-timer": "^7.0.1", + "phpunit/phpunit": "^11.5.46", + "sebastian/environment": "^7.2.1", + "symfony/console": "^6.4.22 || ^7.3.4 || ^8.0.3", + "symfony/process": "^6.4.20 || ^7.3.4 || ^8.0.3" }, "require-dev": { "doctrine/coding-standard": "^12.0.0", "ext-pcov": "*", "ext-posix": "*", - "phpstan/phpstan": "^1.12.6", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpstan/phpstan-strict-rules": "^1.6.1", - "squizlabs/php_codesniffer": "^3.10.3", - "symfony/filesystem": "^6.4.3 || ^7.1.5" + "phpstan/phpstan": "^2.1.33", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.11", + "phpstan/phpstan-strict-rules": "^2.0.7", + "squizlabs/php_codesniffer": "^3.13.5", + "symfony/filesystem": "^6.4.13 || ^7.3.2 || ^8.0.1" }, "bin": [ "bin/paratest", @@ -8757,7 +9320,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.4.9" + "source": "https://github.com/paratestphp/paratest/tree/v7.8.5" }, "funding": [ { @@ -8769,7 +9332,7 @@ "type": "paypal" } ], - "time": "2025-06-25T06:09:59+00:00" + "time": "2026-01-08T08:02:38+00:00" }, { "name": "fakerphp/faker", @@ -9019,16 +9582,16 @@ }, { "name": "iamcal/sql-parser", - "version": "v0.5", + "version": "v0.7", "source": { "type": "git", "url": "https://github.com/iamcal/SQLParser.git", - "reference": "644fd994de3b54e5d833aecf406150aa3b66ca88" + "reference": "610392f38de49a44dab08dc1659960a29874c4b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/iamcal/SQLParser/zipball/644fd994de3b54e5d833aecf406150aa3b66ca88", - "reference": "644fd994de3b54e5d833aecf406150aa3b66ca88", + "url": "https://api.github.com/repos/iamcal/SQLParser/zipball/610392f38de49a44dab08dc1659960a29874c4b8", + "reference": "610392f38de49a44dab08dc1659960a29874c4b8", "shasum": "" }, "require-dev": { @@ -9054,9 +9617,9 @@ "description": "MySQL schema parser", "support": { "issues": "https://github.com/iamcal/SQLParser/issues", - "source": "https://github.com/iamcal/SQLParser/tree/v0.5" + "source": "https://github.com/iamcal/SQLParser/tree/v0.7" }, - "time": "2024-03-22T22:46:32+00:00" + "time": "2026-01-28T22:20:33+00:00" }, { "name": "jean85/pretty-package-versions", @@ -9119,78 +9682,107 @@ "time": "2025-03-19T14:43:43+00:00" }, { - "name": "laravel/breeze", - "version": "v2.3.7", + "name": "larastan/larastan", + "version": "v3.10.0", "source": { "type": "git", - "url": "https://github.com/laravel/breeze.git", - "reference": "73149b5d84be3881b2fdda94b2ad289e7905c1a4" + "url": "https://github.com/larastan/larastan.git", + "reference": "2970f83398154178a739609c244577267c7ee8eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/breeze/zipball/73149b5d84be3881b2fdda94b2ad289e7905c1a4", - "reference": "73149b5d84be3881b2fdda94b2ad289e7905c1a4", + "url": "https://api.github.com/repos/larastan/larastan/zipball/2970f83398154178a739609c244577267c7ee8eb", + "reference": "2970f83398154178a739609c244577267c7ee8eb", "shasum": "" }, "require": { - "illuminate/console": "^11.0|^12.0", - "illuminate/filesystem": "^11.0|^12.0", - "illuminate/support": "^11.0|^12.0", - "illuminate/validation": "^11.0|^12.0", - "php": "^8.2.0", - "symfony/console": "^7.0" + "ext-json": "*", + "iamcal/sql-parser": "^0.7.0", + "illuminate/console": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/container": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/contracts": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/database": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/http": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/pipeline": "^11.44.2 || ^12.4.1 || ^13", + "illuminate/support": "^11.44.2 || ^12.4.1 || ^13", + "php": "^8.2", + "phpstan/phpstan": "^2.2.0" }, "require-dev": { - "laravel/framework": "^11.0|^12.0", - "orchestra/testbench-core": "^9.0|^10.0", - "phpstan/phpstan": "^2.0" + "doctrine/coding-standard": "^14", + "laravel/framework": "^11.44.2 || ^12.7.2 || ^13", + "mockery/mockery": "^1.6.12", + "nikic/php-parser": "^5.4", + "orchestra/canvas": "^v9.2.2 || ^10.0.1 || ^11", + "orchestra/testbench-core": "^9.12.0 || ^10.1 || ^11", + "phpstan/phpstan-deprecation-rules": "^2.0.1", + "phpunit/phpunit": "^10.5.35 || ^11.5.15 || ^12.5.8 || ^13.1.8" }, - "type": "library", + "suggest": { + "orchestra/testbench": "Using Larastan for analysing a package needs Testbench", + "phpmyadmin/sql-parser": "Install to enable Larastan's optional phpMyAdmin-based SQL parser automatically" + }, + "type": "phpstan-extension", "extra": { - "laravel": { - "providers": [ - "Laravel\\Breeze\\BreezeServiceProvider" + "phpstan": { + "includes": [ + "extension.neon" ] + }, + "branch-alias": { + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { - "Laravel\\Breeze\\": "src/" + "Larastan\\Larastan\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ + "authors": [ + { + "name": "Can Vural", + "email": "can9119@gmail.com" + } + ], + "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel", + "keywords": [ + "PHPStan", + "code analyse", + "code analysis", + "larastan", + "laravel", + "package", + "php", + "static analysis" + ], + "support": { + "issues": "https://github.com/larastan/larastan/issues", + "source": "https://github.com/larastan/larastan/tree/v3.10.0" + }, + "funding": [ { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" + "url": "https://github.com/canvural", + "type": "github" } ], - "description": "Minimal Laravel authentication scaffolding with Blade and Tailwind.", - "keywords": [ - "auth", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/breeze/issues", - "source": "https://github.com/laravel/breeze" - }, - "time": "2025-06-17T13:07:20+00:00" + "time": "2026-05-28T08:00:58+00:00" }, { "name": "laravel/pint", - "version": "v1.22.1", + "version": "v1.29.1", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "941d1927c5ca420c22710e98420287169c7bcaf7" + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/941d1927c5ca420c22710e98420287169c7bcaf7", - "reference": "941d1927c5ca420c22710e98420287169c7bcaf7", + "url": "https://api.github.com/repos/laravel/pint/zipball/0770e9b7fafd50d4586881d456d6eb41c9247a80", + "reference": "0770e9b7fafd50d4586881d456d6eb41c9247a80", "shasum": "" }, "require": { @@ -9201,13 +9793,14 @@ "php": "^8.2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.75.0", - "illuminate/view": "^11.44.7", - "larastan/larastan": "^3.4.0", - "laravel-zero/framework": "^11.36.1", + "friendsofphp/php-cs-fixer": "^3.95.1", + "illuminate/view": "^12.56.0", + "larastan/larastan": "^3.9.6", + "laravel-zero/framework": "^12.1.0", "mockery/mockery": "^1.6.12", - "nunomaduro/termwind": "^2.3.1", - "pestphp/pest": "^2.36.0" + "nunomaduro/termwind": "^2.4.0", + "pestphp/pest": "^3.8.6", + "shipfastlabs/agent-detector": "^1.1.3" }, "bin": [ "builds/pint" @@ -9233,6 +9826,7 @@ "description": "An opinionated code formatter for PHP.", "homepage": "https://laravel.com", "keywords": [ + "dev", "format", "formatter", "lint", @@ -9243,7 +9837,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2025-05-08T08:38:12+00:00" + "time": "2026-04-20T15:26:14+00:00" }, { "name": "mockery/mockery", @@ -9390,38 +9984,36 @@ }, { "name": "nunomaduro/collision", - "version": "v8.5.0", + "version": "v8.9.4", "source": { "type": "git", "url": "https://github.com/nunomaduro/collision.git", - "reference": "f5c101b929c958e849a633283adff296ed5f38f5" + "reference": "716af8f95a470e9094cfca09ed897b023be191a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/f5c101b929c958e849a633283adff296ed5f38f5", - "reference": "f5c101b929c958e849a633283adff296ed5f38f5", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/716af8f95a470e9094cfca09ed897b023be191a5", + "reference": "716af8f95a470e9094cfca09ed897b023be191a5", "shasum": "" }, "require": { - "filp/whoops": "^2.16.0", - "nunomaduro/termwind": "^2.1.0", + "filp/whoops": "^2.18.4", + "nunomaduro/termwind": "^2.4.0", "php": "^8.2.0", - "symfony/console": "^7.1.5" + "symfony/console": "^7.4.8 || ^8.0.8" }, "conflict": { - "laravel/framework": "<11.0.0 || >=12.0.0", - "phpunit/phpunit": "<10.5.1 || >=12.0.0" + "laravel/framework": "<11.48.0 || >=14.0.0", + "phpunit/phpunit": "<11.5.50 || >=14.0.0" }, "require-dev": { - "larastan/larastan": "^2.9.8", - "laravel/framework": "^11.28.0", - "laravel/pint": "^1.18.1", - "laravel/sail": "^1.36.0", - "laravel/sanctum": "^4.0.3", - "laravel/tinker": "^2.10.0", - "orchestra/testbench-core": "^9.5.3", - "pestphp/pest": "^2.36.0 || ^3.4.0", - "sebastian/environment": "^6.1.0 || ^7.2.0" + "brianium/paratest": "^7.8.5", + "larastan/larastan": "^3.9.6", + "laravel/framework": "^11.48.0 || ^12.56.0 || ^13.5.0", + "laravel/pint": "^1.29.1", + "orchestra/testbench-core": "^9.12.0 || ^10.12.1 || ^11.2.1", + "pestphp/pest": "^3.8.5 || ^4.4.3 || ^5.0.0", + "sebastian/environment": "^7.2.1 || ^8.0.4 || ^9.3.0" }, "type": "library", "extra": { @@ -9458,6 +10050,7 @@ "cli", "command-line", "console", + "dev", "error", "handling", "laravel", @@ -9483,131 +10076,42 @@ "type": "patreon" } ], - "time": "2024-10-15T16:06:32+00:00" - }, - { - "name": "nunomaduro/larastan", - "version": "v2.11.2", - "source": { - "type": "git", - "url": "https://github.com/larastan/larastan.git", - "reference": "1aae902a5851c03dc1a58cbd9010a0c3ef8def63" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/1aae902a5851c03dc1a58cbd9010a0c3ef8def63", - "reference": "1aae902a5851c03dc1a58cbd9010a0c3ef8def63", - "shasum": "" - }, - "require": { - "ext-json": "*", - "iamcal/sql-parser": "^0.5.0", - "illuminate/console": "^9.52.20 || ^10.48.28 || ^11.41.3", - "illuminate/container": "^9.52.20 || ^10.48.28 || ^11.41.3", - "illuminate/contracts": "^9.52.20 || ^10.48.28 || ^11.41.3", - "illuminate/database": "^9.52.20 || ^10.48.28 || ^11.41.3", - "illuminate/http": "^9.52.20 || ^10.48.28 || ^11.41.3", - "illuminate/pipeline": "^9.52.20 || ^10.48.28 || ^11.41.3", - "illuminate/support": "^9.52.20 || ^10.48.28 || ^11.41.3", - "php": "^8.0.2", - "phpstan/phpstan": "^1.12.17" - }, - "require-dev": { - "doctrine/coding-standard": "^13", - "laravel/framework": "^9.52.20 || ^10.48.28 || ^11.41.3", - "mockery/mockery": "^1.5.1", - "nikic/php-parser": "^4.19.1", - "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.2", - "orchestra/testbench-core": "^7.33.0 || ^8.13.0 || ^9.0.9", - "phpstan/phpstan-deprecation-rules": "^1.2", - "phpunit/phpunit": "^9.6.13 || ^10.5.16" - }, - "suggest": { - "orchestra/testbench": "Using Larastan for analysing a package needs Testbench" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon" - ] - }, - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "psr-4": { - "Larastan\\Larastan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Can Vural", - "email": "can9119@gmail.com" - } - ], - "description": "Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel", - "keywords": [ - "PHPStan", - "code analyse", - "code analysis", - "larastan", - "laravel", - "package", - "php", - "static analysis" - ], - "support": { - "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v2.11.2" - }, - "funding": [ - { - "url": "https://github.com/canvural", - "type": "github" - } - ], - "abandoned": "larastan/larastan", - "time": "2025-06-10T22:06:33+00:00" + "time": "2026-04-21T14:04:20+00:00" }, { "name": "pestphp/pest", - "version": "v2.36.1", + "version": "v3.8.6", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "d66361b272ae4ee4bc33accb5ea3ff385b92e9e1" + "reference": "8871a6f5ef1de8e7c8dee2a270991449a7b6af73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/d66361b272ae4ee4bc33accb5ea3ff385b92e9e1", - "reference": "d66361b272ae4ee4bc33accb5ea3ff385b92e9e1", + "url": "https://api.github.com/repos/pestphp/pest/zipball/8871a6f5ef1de8e7c8dee2a270991449a7b6af73", + "reference": "8871a6f5ef1de8e7c8dee2a270991449a7b6af73", "shasum": "" }, "require": { - "brianium/paratest": "^7.4.9", - "nunomaduro/collision": "^7.11.0|^8.5.0", - "nunomaduro/termwind": "^1.16.0|^2.3.3", - "pestphp/pest-plugin": "^2.1.1", - "pestphp/pest-plugin-arch": "^2.7.0", + "brianium/paratest": "^7.8.5", + "nunomaduro/collision": "^8.9.1", + "nunomaduro/termwind": "^2.4.0", + "pestphp/pest-plugin": "^3.0.0", + "pestphp/pest-plugin-arch": "^3.1.1", + "pestphp/pest-plugin-mutate": "^3.0.5", "php": "^8.2.0", - "phpunit/phpunit": "^10.5.63" + "phpunit/phpunit": "^11.5.50" }, "conflict": { "filp/whoops": "<2.16.0", - "phpunit/phpunit": ">10.5.63", - "sebastian/exporter": "<5.1.0", + "phpunit/phpunit": ">11.5.50", + "sebastian/exporter": "<6.0.0", "webmozart/assert": "<1.11.0" }, "require-dev": { - "pestphp/pest-dev-tools": "^2.17.0", - "pestphp/pest-plugin-type-coverage": "^2.8.7", - "symfony/process": "^6.4.0|^7.4.4" + "pestphp/pest-dev-tools": "^3.4.0", + "pestphp/pest-plugin-type-coverage": "^3.6.1", + "symfony/process": "^7.4.5" }, "bin": [ "bin/pest" @@ -9616,6 +10120,8 @@ "extra": { "pest": { "plugins": [ + "Pest\\Mutate\\Plugins\\Mutate", + "Pest\\Plugins\\Configuration", "Pest\\Plugins\\Bail", "Pest\\Plugins\\Cache", "Pest\\Plugins\\Coverage", @@ -9670,7 +10176,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v2.36.1" + "source": "https://github.com/pestphp/pest/tree/v3.8.6" }, "funding": [ { @@ -9682,34 +10188,34 @@ "type": "github" } ], - "time": "2026-01-28T02:02:41+00:00" + "time": "2026-03-10T21:04:33+00:00" }, { "name": "pestphp/pest-plugin", - "version": "v2.1.1", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin.git", - "reference": "e05d2859e08c2567ee38ce8b005d044e72648c0b" + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e05d2859e08c2567ee38ce8b005d044e72648c0b", - "reference": "e05d2859e08c2567ee38ce8b005d044e72648c0b", + "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/e79b26c65bc11c41093b10150c1341cc5cdbea83", + "reference": "e79b26c65bc11c41093b10150c1341cc5cdbea83", "shasum": "" }, "require": { "composer-plugin-api": "^2.0.0", "composer-runtime-api": "^2.2.2", - "php": "^8.1" + "php": "^8.2" }, "conflict": { - "pestphp/pest": "<2.2.3" + "pestphp/pest": "<3.0.0" }, "require-dev": { - "composer/composer": "^2.5.8", - "pestphp/pest": "^2.16.0", - "pestphp/pest-dev-tools": "^2.16.0" + "composer/composer": "^2.7.9", + "pestphp/pest": "^3.0.0", + "pestphp/pest-dev-tools": "^3.0.0" }, "type": "composer-plugin", "extra": { @@ -9736,7 +10242,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin/tree/v2.1.1" + "source": "https://github.com/pestphp/pest-plugin/tree/v3.0.0" }, "funding": [ { @@ -9752,31 +10258,30 @@ "type": "patreon" } ], - "time": "2023-08-22T08:40:06+00:00" + "time": "2024-09-08T23:21:41+00:00" }, { "name": "pestphp/pest-plugin-arch", - "version": "v2.7.0", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-arch.git", - "reference": "d23b2d7498475354522c3818c42ef355dca3fcda" + "reference": "db7bd9cb1612b223e16618d85475c6f63b9c8daa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/d23b2d7498475354522c3818c42ef355dca3fcda", - "reference": "d23b2d7498475354522c3818c42ef355dca3fcda", + "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/db7bd9cb1612b223e16618d85475c6f63b9c8daa", + "reference": "db7bd9cb1612b223e16618d85475c6f63b9c8daa", "shasum": "" }, "require": { - "nunomaduro/collision": "^7.10.0|^8.1.0", - "pestphp/pest-plugin": "^2.1.1", - "php": "^8.1", + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", "ta-tikoma/phpunit-architecture-test": "^0.8.4" }, "require-dev": { - "pestphp/pest": "^2.33.0", - "pestphp/pest-dev-tools": "^2.16.0" + "pestphp/pest": "^3.8.1", + "pestphp/pest-dev-tools": "^3.4.0" }, "type": "library", "extra": { @@ -9811,7 +10316,7 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-arch/tree/v2.7.0" + "source": "https://github.com/pestphp/pest-plugin-arch/tree/v3.1.1" }, "funding": [ { @@ -9823,31 +10328,31 @@ "type": "github" } ], - "time": "2024-01-26T09:46:42+00:00" + "time": "2025-04-16T22:59:48+00:00" }, { "name": "pestphp/pest-plugin-laravel", - "version": "v2.4.0", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/pestphp/pest-plugin-laravel.git", - "reference": "53df51169a7f9595e06839cce638c73e59ace5e8" + "reference": "6801be82fd92b96e82dd72e563e5674b1ce365fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/53df51169a7f9595e06839cce638c73e59ace5e8", - "reference": "53df51169a7f9595e06839cce638c73e59ace5e8", + "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/6801be82fd92b96e82dd72e563e5674b1ce365fc", + "reference": "6801be82fd92b96e82dd72e563e5674b1ce365fc", "shasum": "" }, "require": { - "laravel/framework": "^10.48.9|^11.5.0", - "pestphp/pest": "^2.34.7", - "php": "^8.1.0" + "laravel/framework": "^11.39.1|^12.9.2", + "pestphp/pest": "^3.8.2", + "php": "^8.2.0" }, "require-dev": { - "laravel/dusk": "^7.13.0", - "orchestra/testbench": "^8.22.3|^9.0.4", - "pestphp/pest-dev-tools": "^2.16.0" + "laravel/dusk": "^8.2.13|dev-develop", + "orchestra/testbench": "^9.9.0|^10.2.1", + "pestphp/pest-dev-tools": "^3.4.0" }, "type": "library", "extra": { @@ -9885,19 +10390,91 @@ "unit" ], "support": { - "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v2.4.0" + "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v3.2.0" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2025-04-21T07:40:53+00:00" + }, + { + "name": "pestphp/pest-plugin-mutate", + "version": "v3.0.5", + "source": { + "type": "git", + "url": "https://github.com/pestphp/pest-plugin-mutate.git", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "reference": "e10dbdc98c9e2f3890095b4fe2144f63a5717e08", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.2.0", + "pestphp/pest-plugin": "^3.0.0", + "php": "^8.2", + "psr/simple-cache": "^3.0.0" + }, + "require-dev": { + "pestphp/pest": "^3.0.8", + "pestphp/pest-dev-tools": "^3.0.0", + "pestphp/pest-plugin-type-coverage": "^3.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Pest\\Mutate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sandro Gehri", + "email": "sandrogehri@gmail.com" + } + ], + "description": "Mutates your code to find untested cases", + "keywords": [ + "framework", + "mutate", + "mutation", + "pest", + "php", + "plugin", + "test", + "testing", + "unit" + ], + "support": { + "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v3.0.5" }, "funding": [ { "url": "https://www.paypal.com/paypalme/enunomaduro", "type": "custom" }, + { + "url": "https://github.com/gehrisandro", + "type": "github" + }, { "url": "https://github.com/nunomaduro", "type": "github" } ], - "time": "2024-04-27T10:41:54+00:00" + "time": "2024-09-22T07:54:40+00:00" }, { "name": "phar-io/manifest", @@ -10019,20 +10596,15 @@ }, { "name": "phpstan/phpstan", - "version": "1.12.27", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "3a6e423c076ab39dfedc307e2ac627ef579db162" - }, + "version": "2.2.1", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3a6e423c076ab39dfedc307e2ac627ef579db162", - "reference": "3a6e423c076ab39dfedc307e2ac627ef579db162", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/dea9c8f2d25cc849391042b71e429c1a4bf82660", + "reference": "dea9c8f2d25cc849391042b71e429c1a4bf82660", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -10051,6 +10623,17 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ "dev", @@ -10073,39 +10656,39 @@ "type": "github" } ], - "time": "2025-05-21T20:51:45+00:00" + "time": "2026-05-28T14:44:12+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "10.1.16", + "version": "11.0.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", - "theseer/tokenizer": "^1.2.3" + "nikic/php-parser": "^5.7.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.1", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.3.1" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^11.5.46" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -10114,7 +10697,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1.x-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { @@ -10143,40 +10726,52 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" } ], - "time": "2024-08-22T04:31:57+00:00" + "time": "2025-12-24T07:01:01+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -10204,36 +10799,48 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2026-02-02T13:52:54+00:00" }, { "name": "phpunit/php-invoker", - "version": "4.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcntl": "*" @@ -10241,7 +10848,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -10267,7 +10874,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { @@ -10275,32 +10883,32 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { "name": "phpunit/php-text-template", - "version": "3.0.1", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -10327,7 +10935,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { @@ -10335,32 +10943,32 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { "name": "phpunit/php-timer", - "version": "6.0.0", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -10386,7 +10994,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { @@ -10394,20 +11003,20 @@ "type": "github" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "10.5.63", + "version": "11.5.50", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "33198268dad71e926626b618f3ec3966661e4d90" + "reference": "fdfc727f0fcacfeb8fcb30c7e5da173125b58be3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90", - "reference": "33198268dad71e926626b618f3ec3966661e4d90", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fdfc727f0fcacfeb8fcb30c7e5da173125b58be3", + "reference": "fdfc727f0fcacfeb8fcb30c7e5da173125b58be3", "shasum": "" }, "require": { @@ -10420,23 +11029,23 @@ "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.5", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.4", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.1", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.12", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.3", + "sebastian/comparator": "^6.3.3", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.2", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.3", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" @@ -10447,7 +11056,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.5-dev" + "dev-main": "11.5-dev" } }, "autoload": { @@ -10479,7 +11088,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.50" }, "funding": [ { @@ -10503,32 +11112,32 @@ "type": "tidelift" } ], - "time": "2026-01-27T05:48:37+00:00" + "time": "2026-01-27T05:59:18+00:00" }, { "name": "sebastian/cli-parser", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -10552,7 +11161,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" }, "funding": [ { @@ -10560,32 +11169,32 @@ "type": "github" } ], - "time": "2024-03-02T07:12:49+00:00" + "time": "2024-07-03T04:41:36+00:00" }, { "name": "sebastian/code-unit", - "version": "2.0.0", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -10608,7 +11217,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" }, "funding": [ { @@ -10616,32 +11226,32 @@ "type": "github" } ], - "time": "2023-02-03T06:58:43+00:00" + "time": "2025-03-19T07:56:08+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -10663,7 +11273,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" }, "funding": [ { @@ -10671,36 +11282,39 @@ "type": "github" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "5.0.5", + "version": "6.3.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d" + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d", - "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -10740,7 +11354,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3" }, "funding": [ { @@ -10760,33 +11374,33 @@ "type": "tidelift" } ], - "time": "2026-01-24T09:25:16+00:00" + "time": "2026-01-24T09:26:40+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -10810,7 +11424,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" }, "funding": [ { @@ -10818,33 +11432,33 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { "name": "sebastian/diff", - "version": "5.1.1", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -10877,7 +11491,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" }, "funding": [ { @@ -10885,27 +11499,27 @@ "type": "github" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2024-07-03T04:53:05+00:00" }, { "name": "sebastian/environment", - "version": "6.1.0", + "version": "7.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.3" }, "suggest": { "ext-posix": "*" @@ -10913,7 +11527,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -10941,42 +11555,54 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" } ], - "time": "2024-03-23T08:47:14+00:00" + "time": "2025-05-21T11:55:47+00:00" }, { "name": "sebastian/exporter", - "version": "5.1.4", + "version": "6.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "0735b90f4da94969541dac1da743446e276defa6" + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", - "reference": "0735b90f4da94969541dac1da743446e276defa6", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -11019,7 +11645,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" }, "funding": [ { @@ -11039,35 +11665,35 @@ "type": "tidelift" } ], - "time": "2025-09-24T06:09:11+00:00" + "time": "2025-09-24T06:12:51+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.2", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -11093,7 +11719,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" }, "funding": [ { @@ -11101,33 +11727,33 @@ "type": "github" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2024-07-03T04:57:36+00:00" }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -11151,7 +11777,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" }, "funding": [ { @@ -11159,34 +11785,34 @@ "type": "github" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { "name": "sebastian/object-enumerator", - "version": "5.0.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -11208,7 +11834,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { @@ -11216,32 +11843,32 @@ "type": "github" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { "name": "sebastian/object-reflector", - "version": "3.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -11263,7 +11890,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { @@ -11271,32 +11899,32 @@ "type": "github" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { "name": "sebastian/recursion-context", - "version": "5.0.1", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", - "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -11327,7 +11955,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" }, "funding": [ { @@ -11347,32 +11975,32 @@ "type": "tidelift" } ], - "time": "2025-08-10T07:50:56+00:00" + "time": "2025-08-13T04:42:22+00:00" }, { "name": "sebastian/type", - "version": "4.0.0", + "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -11395,37 +12023,50 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2025-08-09T06:55:48+00:00" }, { "name": "sebastian/version", - "version": "4.0.1", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -11448,7 +12089,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, "funding": [ { @@ -11456,387 +12098,59 @@ "type": "github" } ], - "time": "2023-02-07T11:34:05+00:00" - }, - { - "name": "spatie/backtrace", - "version": "1.7.4", - "source": { - "type": "git", - "url": "https://github.com/spatie/backtrace.git", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/cd37a49fce7137359ac30ecc44ef3e16404cccbe", - "reference": "cd37a49fce7137359ac30ecc44ef3e16404cccbe", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "ext-json": "*", - "laravel/serializable-closure": "^1.3 || ^2.0", - "phpunit/phpunit": "^9.3 || ^11.4.3", - "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6", - "symfony/var-dumper": "^5.1 || ^6.0 || ^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Backtrace\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van de Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "A better backtrace", - "homepage": "https://github.com/spatie/backtrace", - "keywords": [ - "Backtrace", - "spatie" - ], - "support": { - "source": "https://github.com/spatie/backtrace/tree/1.7.4" - }, - "funding": [ - { - "url": "https://github.com/sponsors/spatie", - "type": "github" - }, - { - "url": "https://spatie.be/open-source/support-us", - "type": "other" - } - ], - "time": "2025-05-08T15:41:09+00:00" - }, - { - "name": "spatie/error-solutions", - "version": "1.1.3", - "source": { - "type": "git", - "url": "https://github.com/spatie/error-solutions.git", - "reference": "e495d7178ca524f2dd0fe6a1d99a1e608e1c9936" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/error-solutions/zipball/e495d7178ca524f2dd0fe6a1d99a1e608e1c9936", - "reference": "e495d7178ca524f2dd0fe6a1d99a1e608e1c9936", - "shasum": "" - }, - "require": { - "php": "^8.0" - }, - "require-dev": { - "illuminate/broadcasting": "^10.0|^11.0|^12.0", - "illuminate/cache": "^10.0|^11.0|^12.0", - "illuminate/support": "^10.0|^11.0|^12.0", - "livewire/livewire": "^2.11|^3.5.20", - "openai-php/client": "^0.10.1", - "orchestra/testbench": "8.22.3|^9.0|^10.0", - "pestphp/pest": "^2.20|^3.0", - "phpstan/phpstan": "^2.1", - "psr/simple-cache": "^3.0", - "psr/simple-cache-implementation": "^3.0", - "spatie/ray": "^1.28", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "vlucas/phpdotenv": "^5.5" - }, - "suggest": { - "openai-php/client": "Require get solutions from OpenAI", - "simple-cache-implementation": "To cache solutions from OpenAI" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Ignition\\": "legacy/ignition", - "Spatie\\ErrorSolutions\\": "src", - "Spatie\\LaravelIgnition\\": "legacy/laravel-ignition" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ruben Van Assche", - "email": "ruben@spatie.be", - "role": "Developer" - } - ], - "description": "This is my package error-solutions", - "homepage": "https://github.com/spatie/error-solutions", - "keywords": [ - "error-solutions", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/error-solutions/issues", - "source": "https://github.com/spatie/error-solutions/tree/1.1.3" - }, - "funding": [ - { - "url": "https://github.com/Spatie", - "type": "github" - } - ], - "time": "2025-02-14T12:29:50+00:00" - }, - { - "name": "spatie/flare-client-php", - "version": "1.10.1", - "source": { - "type": "git", - "url": "https://github.com/spatie/flare-client-php.git", - "reference": "bf1716eb98bd689451b071548ae9e70738dce62f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/bf1716eb98bd689451b071548ae9e70738dce62f", - "reference": "bf1716eb98bd689451b071548ae9e70738dce62f", - "shasum": "" - }, - "require": { - "illuminate/pipeline": "^8.0|^9.0|^10.0|^11.0|^12.0", - "php": "^8.0", - "spatie/backtrace": "^1.6.1", - "symfony/http-foundation": "^5.2|^6.0|^7.0", - "symfony/mime": "^5.2|^6.0|^7.0", - "symfony/process": "^5.2|^6.0|^7.0", - "symfony/var-dumper": "^5.2|^6.0|^7.0" - }, - "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.5.0", - "pestphp/pest": "^1.20|^2.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "spatie/pest-plugin-snapshots": "^1.0|^2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.3.x-dev" - } - }, - "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Spatie\\FlareClient\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Send PHP errors to Flare", - "homepage": "https://github.com/spatie/flare-client-php", - "keywords": [ - "exception", - "flare", - "reporting", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/flare-client-php/issues", - "source": "https://github.com/spatie/flare-client-php/tree/1.10.1" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-02-14T13:42:06+00:00" - }, - { - "name": "spatie/ignition", - "version": "1.15.1", - "source": { - "type": "git", - "url": "https://github.com/spatie/ignition.git", - "reference": "31f314153020aee5af3537e507fef892ffbf8c85" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/ignition/zipball/31f314153020aee5af3537e507fef892ffbf8c85", - "reference": "31f314153020aee5af3537e507fef892ffbf8c85", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "php": "^8.0", - "spatie/error-solutions": "^1.0", - "spatie/flare-client-php": "^1.7", - "symfony/console": "^5.4|^6.0|^7.0", - "symfony/var-dumper": "^5.4|^6.0|^7.0" - }, - "require-dev": { - "illuminate/cache": "^9.52|^10.0|^11.0|^12.0", - "mockery/mockery": "^1.4", - "pestphp/pest": "^1.20|^2.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "psr/simple-cache-implementation": "*", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/process": "^5.4|^6.0|^7.0", - "vlucas/phpdotenv": "^5.5" - }, - "suggest": { - "openai-php/client": "Require get solutions from OpenAI", - "simple-cache-implementation": "To cache solutions from OpenAI" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.5.x-dev" - } - }, - "autoload": { - "psr-4": { - "Spatie\\Ignition\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Spatie", - "email": "info@spatie.be", - "role": "Developer" - } - ], - "description": "A beautiful error page for PHP applications.", - "homepage": "https://flareapp.io/ignition", - "keywords": [ - "error", - "flare", - "laravel", - "page" - ], - "support": { - "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", - "forum": "https://twitter.com/flareappio", - "issues": "https://github.com/spatie/ignition/issues", - "source": "https://github.com/spatie/ignition" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-02-21T14:31:39+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "spatie/laravel-ignition", - "version": "2.9.1", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/spatie/laravel-ignition.git", - "reference": "1baee07216d6748ebd3a65ba97381b051838707a" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/1baee07216d6748ebd3a65ba97381b051838707a", - "reference": "1baee07216d6748ebd3a65ba97381b051838707a", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "illuminate/support": "^10.0|^11.0|^12.0", - "php": "^8.1", - "spatie/ignition": "^1.15", - "symfony/console": "^6.2.3|^7.0", - "symfony/var-dumper": "^6.2.3|^7.0" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, "require-dev": { - "livewire/livewire": "^2.11|^3.3.5", - "mockery/mockery": "^1.5.1", - "openai-php/client": "^0.8.1|^0.10", - "orchestra/testbench": "8.22.3|^9.0|^10.0", - "pestphp/pest": "^2.34|^3.7", - "phpstan/extension-installer": "^1.3.1", - "phpstan/phpstan-deprecation-rules": "^1.1.1|^2.0", - "phpstan/phpstan-phpunit": "^1.3.16|^2.0", - "vlucas/phpdotenv": "^5.5" - }, - "suggest": { - "openai-php/client": "Require get solutions from OpenAI", - "psr/simple-cache-implementation": "Needed to cache solutions from OpenAI" + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" }, "type": "library", - "extra": { - "laravel": { - "aliases": { - "Flare": "Spatie\\LaravelIgnition\\Facades\\Flare" - }, - "providers": [ - "Spatie\\LaravelIgnition\\IgnitionServiceProvider" - ] - } - }, "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Spatie\\LaravelIgnition\\": "src" - } + "classmap": [ + "lib/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Spatie", - "email": "info@spatie.be", - "role": "Developer" - } - ], - "description": "A beautiful error page for Laravel applications.", - "homepage": "https://flareapp.io/ignition", + "description": "A static analysis tool to detect side effects in PHP code", "keywords": [ - "error", - "flare", - "laravel", - "page" + "static analysis" ], "support": { - "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", - "forum": "https://twitter.com/flareappio", - "issues": "https://github.com/spatie/laravel-ignition/issues", - "source": "https://github.com/spatie/laravel-ignition" + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" }, "funding": [ { - "url": "https://github.com/spatie", + "url": "https://github.com/staabm", "type": "github" } ], - "time": "2025-02-20T13:13:55+00:00" + "time": "2024-10-20T05:08:20+00:00" }, { "name": "ta-tikoma/phpunit-architecture-test", diff --git a/composer.phar b/composer.phar new file mode 100644 index 00000000000..e3253ebc9dd Binary files /dev/null and b/composer.phar differ diff --git a/config/activity.php b/config/activity.php deleted file mode 100644 index 0e6d1d9af47..00000000000 --- a/config/activity.php +++ /dev/null @@ -1,6 +0,0 @@ - env('APP_ACTIVITY_PRUNE_DAYS', 90), -]; diff --git a/config/app.php b/config/app.php index c47e064b1c7..0ebbe5abd78 100644 --- a/config/app.php +++ b/config/app.php @@ -1,204 +1,30 @@ 'canary', /* - |-------------------------------------------------------------------------- - | Application Name - |-------------------------------------------------------------------------- - | - | This value is the name of your application. This value is used when the - | framework needs to place the application's name in a notification or - | any other location as required by the application or its packages. - | - */ - - 'name' => env('APP_NAME', 'Laravel'), - - /* - |-------------------------------------------------------------------------- - | Application Environment - |-------------------------------------------------------------------------- - | - | This value determines the "environment" your application is currently - | running in. This may determine how you prefer to configure various - | services the application utilizes. Set this in your ".env" file. - | - */ - - 'env' => env('APP_ENV', 'production'), - - /* - |-------------------------------------------------------------------------- - | Application Debug Mode - |-------------------------------------------------------------------------- - | - | When your application is in debug mode, detailed error messages with - | stack traces will be shown on every error that occurs within your - | application. If disabled, a simple generic error page is shown. - | - */ - - 'debug' => (bool) env('APP_DEBUG', false), - - /* - |-------------------------------------------------------------------------- - | Application URL - |-------------------------------------------------------------------------- - | - | This URL is used by the console to properly generate URLs when using - | the Artisan command line tool. You should set this to the root of - | your application so that it is used when running Artisan tasks. - | - */ - - 'url' => env('APP_URL', 'http://localhost'), - - 'asset_url' => env('ASSET_URL'), - - /* - |-------------------------------------------------------------------------- - | Application Timezone - |-------------------------------------------------------------------------- - | - | Here you may specify the default timezone for your application, which - | will be used by the PHP date and date-time functions. We have gone - | ahead and set this to a sensible default for you out of the box. - | - */ - - 'timezone' => 'UTC', - - /* - |-------------------------------------------------------------------------- - | Application Locale Configuration - |-------------------------------------------------------------------------- - | - | The application locale determines the default locale that will be used - | by the translation service provider. You are free to set this value - | to any of the locales which will be supported by the application. - | - */ - - 'locale' => 'en_US', - - /* - |-------------------------------------------------------------------------- - | Application Fallback Locale - |-------------------------------------------------------------------------- - | - | The fallback locale determines the locale to use when the current one - | is not available. You may change the value to correspond to any of - | the language folders that are provided through your application. - | - */ - - 'fallback_locale' => 'en_US', - - /* - |-------------------------------------------------------------------------- - | Faker Locale - |-------------------------------------------------------------------------- - | - | This locale will be used by the Faker PHP library when generating fake - | data for your database seeds. For example, this will be used to get - | localized telephone numbers, street address information and more. - | - */ - - 'faker_locale' => 'en_US', - - /* - |-------------------------------------------------------------------------- - | Encryption Key - |-------------------------------------------------------------------------- - | - | This key is used by the Illuminate encrypter service and should be set - | to a random, 32 character string, otherwise these encrypted strings - | will not be safe. Please do this before deploying an application! - | - */ - - 'key' => env('APP_KEY'), - - 'cipher' => 'AES-256-CBC', - - /* - |-------------------------------------------------------------------------- - | Maintenance Mode Driver - |-------------------------------------------------------------------------- - | - | These configuration options determine the driver used to determine and - | manage Laravel's "maintenance mode" status. The "cache" driver will - | allow maintenance mode to be controlled across multiple machines. - | - | Supported drivers: "file", "cache" - | - */ - + * Only the store is overridden here. Laravel defaults it to the `database` + * cache store, which reads a `cache` table Convoy has no migration for, so + * any install that selects the `cache` driver fails on every request with + * "relation cache does not exist" -- Redis is the store Convoy actually has. + * + * The driver keeps Laravel's `file` default: file-based maintenance mode + * only marks down the process that ran the command, which is correct for a + * single-process install and wrong for a containerised one. Deployments that + * run web, worker and scheduler separately set APP_MAINTENANCE_DRIVER=cache + * so that `artisan down` takes all three out at once. + */ 'maintenance' => [ - 'driver' => 'file', - // 'store' => 'redis', + 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), + 'store' => env('APP_MAINTENANCE_STORE', 'redis'), ], - /* - |-------------------------------------------------------------------------- - | Autoloaded Service Providers - |-------------------------------------------------------------------------- - | - | The service providers listed here will be automatically loaded on the - | request to your application. Feel free to add your own services to - | this array to grant expanded functionality to your applications. - | - */ - - 'providers' => ServiceProvider::defaultProviders()->merge([ - /* - * Package Service Providers... - */ - - /* - * Application Service Providers... - */ - Convoy\Providers\ActivityLogServiceProvider::class, - Convoy\Providers\AppServiceProvider::class, - Convoy\Providers\AuthServiceProvider::class, - Convoy\Providers\BroadcastServiceProvider::class, - Convoy\Providers\EventServiceProvider::class, - Convoy\Providers\HorizonServiceProvider::class, - Convoy\Providers\RouteServiceProvider::class, - Convoy\Providers\RepositoryServiceProvider::class, - Convoy\Providers\FortifyServiceProvider::class, - ])->toArray(), - - /* - |-------------------------------------------------------------------------- - | Class Aliases - |-------------------------------------------------------------------------- - | - | This array of class aliases will be registered when this application - | is started. However, feel free to register as many as you wish as - | the aliases are "lazy" loaded so they don't hinder performance. - | - */ - 'aliases' => Facade::defaultAliases()->merge([ // Custom Facades - 'Activity' => Convoy\Facades\Activity::class, - 'LogBatch' => Convoy\Facades\LogBatch::class, - 'LogTarget' => Convoy\Facades\LogTarget::class, + 'Audit' => Audit::class, ])->toArray(), - ]; diff --git a/config/audit.php b/config/audit.php new file mode 100644 index 00000000000..cfcad19489a --- /dev/null +++ b/config/audit.php @@ -0,0 +1,18 @@ + env('APP_AUDIT_PRUNE_DAYS', 90), + + /* + * Rows deleted per statement by the pruner, so a long-neglected install does not issue one + * enormous DELETE. + */ + 'prune_chunk' => env('APP_AUDIT_PRUNE_CHUNK', 1000), +]; diff --git a/config/auth.php b/config/auth.php deleted file mode 100644 index 0de49c42200..00000000000 --- a/config/auth.php +++ /dev/null @@ -1,115 +0,0 @@ - [ - 'guard' => 'web', - 'passwords' => 'users', - ], - - /* - |-------------------------------------------------------------------------- - | Authentication Guards - |-------------------------------------------------------------------------- - | - | Next, you may define every authentication guard for your application. - | Of course, a great default configuration has been defined for you - | here which uses session storage and the Eloquent user provider. - | - | All authentication drivers have a user provider. This defines how the - | users are actually retrieved out of your database or other storage - | mechanisms used by this application to persist your user's data. - | - | Supported: "session" - | - */ - - 'guards' => [ - 'web' => [ - 'driver' => 'session', - 'provider' => 'users', - ], - ], - - /* - |-------------------------------------------------------------------------- - | User Providers - |-------------------------------------------------------------------------- - | - | All authentication drivers have a user provider. This defines how the - | users are actually retrieved out of your database or other storage - | mechanisms used by this application to persist your user's data. - | - | If you have multiple user tables or models you may configure multiple - | sources which represent each model / table. These sources may then - | be assigned to any extra authentication guards you have defined. - | - | Supported: "database", "eloquent" - | - */ - - 'providers' => [ - 'users' => [ - 'driver' => 'eloquent', - 'model' => Convoy\Models\User::class, - ], - - // 'users' => [ - // 'driver' => 'database', - // 'table' => 'users', - // ], - ], - - /* - |-------------------------------------------------------------------------- - | Resetting Passwords - |-------------------------------------------------------------------------- - | - | You may specify multiple password reset configurations if you have more - | than one user table or model in the application and you want to have - | separate password reset settings based on the specific user types. - | - | The expiry time is the number of minutes that each reset token will be - | considered valid. This security feature keeps tokens short-lived so - | they have less time to be guessed. You may change this as needed. - | - | The throttle setting is the number of seconds a user must wait before - | generating more password reset tokens. This prevents the user from - | quickly generating a very large amount of password reset tokens. - | - */ - - 'passwords' => [ - 'users' => [ - 'provider' => 'users', - 'table' => 'password_reset_tokens', - 'expire' => 60, - 'throttle' => 60, - ], - ], - - /* - |-------------------------------------------------------------------------- - | Password Confirmation Timeout - |-------------------------------------------------------------------------- - | - | Here you may define the amount of seconds before a password confirmation - | times out and the user is prompted to re-enter their password via the - | confirmation screen. By default, the timeout lasts for three hours. - | - */ - - 'password_timeout' => 10800, - -]; diff --git a/config/broadcasting.php b/config/broadcasting.php deleted file mode 100644 index 9e4d4aa44b5..00000000000 --- a/config/broadcasting.php +++ /dev/null @@ -1,70 +0,0 @@ - env('BROADCAST_DRIVER', 'null'), - - /* - |-------------------------------------------------------------------------- - | Broadcast Connections - |-------------------------------------------------------------------------- - | - | Here you may define all of the broadcast connections that will be used - | to broadcast events to other systems or over websockets. Samples of - | each available type of connection are provided inside this array. - | - */ - - 'connections' => [ - - 'pusher' => [ - 'driver' => 'pusher', - 'key' => env('PUSHER_APP_KEY'), - 'secret' => env('PUSHER_APP_SECRET'), - 'app_id' => env('PUSHER_APP_ID'), - 'options' => [ - 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', - 'port' => env('PUSHER_PORT', 443), - 'scheme' => env('PUSHER_SCHEME', 'https'), - 'encrypted' => true, - 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https', - ], - 'client_options' => [ - // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html - ], - ], - - 'ably' => [ - 'driver' => 'ably', - 'key' => env('ABLY_KEY'), - ], - - 'redis' => [ - 'driver' => 'redis', - 'connection' => 'default', - ], - - 'log' => [ - 'driver' => 'log', - ], - - 'null' => [ - 'driver' => 'null', - ], - - ], - -]; diff --git a/config/cache.php b/config/cache.php deleted file mode 100644 index 33bb29546eb..00000000000 --- a/config/cache.php +++ /dev/null @@ -1,110 +0,0 @@ - env('CACHE_DRIVER', 'file'), - - /* - |-------------------------------------------------------------------------- - | Cache Stores - |-------------------------------------------------------------------------- - | - | Here you may define all of the cache "stores" for your application as - | well as their drivers. You may even define multiple stores for the - | same cache driver to group types of items stored in your caches. - | - | Supported drivers: "apc", "array", "database", "file", - | "memcached", "redis", "dynamodb", "octane", "null" - | - */ - - 'stores' => [ - - 'apc' => [ - 'driver' => 'apc', - ], - - 'array' => [ - 'driver' => 'array', - 'serialize' => false, - ], - - 'database' => [ - 'driver' => 'database', - 'table' => 'cache', - 'connection' => null, - 'lock_connection' => null, - ], - - 'file' => [ - 'driver' => 'file', - 'path' => storage_path('framework/cache/data'), - ], - - 'memcached' => [ - 'driver' => 'memcached', - 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), - 'sasl' => [ - env('MEMCACHED_USERNAME'), - env('MEMCACHED_PASSWORD'), - ], - 'options' => [ - // Memcached::OPT_CONNECT_TIMEOUT => 2000, - ], - 'servers' => [ - [ - 'host' => env('MEMCACHED_HOST', '127.0.0.1'), - 'port' => env('MEMCACHED_PORT', 11211), - 'weight' => 100, - ], - ], - ], - - 'redis' => [ - 'driver' => 'redis', - 'connection' => 'cache', - 'lock_connection' => 'default', - ], - - 'dynamodb' => [ - 'driver' => 'dynamodb', - 'key' => env('AWS_ACCESS_KEY_ID'), - 'secret' => env('AWS_SECRET_ACCESS_KEY'), - 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), - 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), - 'endpoint' => env('DYNAMODB_ENDPOINT'), - ], - - 'octane' => [ - 'driver' => 'octane', - ], - - ], - - /* - |-------------------------------------------------------------------------- - | Cache Key Prefix - |-------------------------------------------------------------------------- - | - | When utilizing the APC, database, memcached, Redis, or DynamoDB cache - | stores there might be other applications using the same cache. For - | that reason, you may prefix every cache key to avoid collisions. - | - */ - - 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), - -]; diff --git a/config/convoy.php b/config/convoy.php index d7525d06147..153eb91b032 100644 --- a/config/convoy.php +++ b/config/convoy.php @@ -12,4 +12,38 @@ 'timeout' => env('GUZZLE_TIMEOUT', 15), 'connect_timeout' => env('GUZZLE_CONNECT_TIMEOUT', 5), ], + + /* +|-------------------------------------------------------------------------- +| Update Checker +|-------------------------------------------------------------------------- +| +| The GitHub repository whose published releases the panel compares itself +| against. Only forks that cut their own releases need to change this. +*/ + /* + | Where an uploaded file the panel hosts lives -- a disk image or an ISO -- + | and how long the URL a node fetches it with stays valid. The link only has to survive one download, so it is + | minted per fetch and expires soon after -- a node never holds a credential + | for the panel's storage, and a leaked URL is worthless by the time anyone + | finds it. + */ + 'artifacts' => [ + 'disk' => env('ARTIFACTS_DISK', 'artifacts'), + 'url_ttl_minutes' => env('ARTIFACTS_URL_TTL_MINUTES', 120), + ], + + /* + | Where uploaded profile pictures live. Not the `artifacts` disk: those are + | multi-gigabyte files a node fetches once over an expiring link, while an + | avatar is a 30KB file the panel serves on every page. Point this at `s3` + | to move them off the box. + */ + 'avatars' => [ + 'disk' => env('AVATARS_DISK', 'local'), + ], + + 'updates' => [ + 'repository' => env('UPDATE_CHECK_REPOSITORY', 'ConvoyPanel/panel'), + ], ]; diff --git a/config/cors.php b/config/cors.php deleted file mode 100644 index 8a39e6daa63..00000000000 --- a/config/cors.php +++ /dev/null @@ -1,34 +0,0 @@ - ['api/*', 'sanctum/csrf-cookie'], - - 'allowed_methods' => ['*'], - - 'allowed_origins' => ['*'], - - 'allowed_origins_patterns' => [], - - 'allowed_headers' => ['*'], - - 'exposed_headers' => [], - - 'max_age' => 0, - - 'supports_credentials' => false, - -]; diff --git a/config/data.php b/config/data.php new file mode 100644 index 00000000000..83b94a5278d --- /dev/null +++ b/config/data.php @@ -0,0 +1,215 @@ + DATE_ATOM, + + /* + * When transforming or casting dates, the following timezone will be used to + * convert the date to the correct timezone. If set to null no timezone will + * be passed. + */ + 'date_timezone' => null, + + /* + * It is possible to enable certain features of the package, these would otherwise + * be breaking changes, and thus they are disabled by default. In the next major + * version of the package, these features will be enabled by default. + */ + 'features' => [ + 'cast_and_transform_iterables' => false, + + /* + * When trying to set a computed property value, the package will throw an exception. + * You can disable this behaviour by setting this option to true, which will then just + * ignore the value being passed into the computed property and recalculate it. + */ + 'ignore_exception_when_trying_to_set_computed_property_value' => false, + ], + + /* + * Global transformers will take complex types and transform them into simple + * types. + */ + 'transformers' => [ + DateTimeInterface::class => DateTimeInterfaceTransformer::class, + Arrayable::class => ArrayableTransformer::class, + BackedEnum::class => EnumTransformer::class, + ], + + /* + * Global casts will cast values into complex types when creating a data + * object from simple types. + */ + 'casts' => [ + DateTimeInterface::class => DateTimeInterfaceCast::class, + BackedEnum::class => EnumCast::class, + // Enumerable::class => Spatie\LaravelData\Casts\EnumerableCast::class, + ], + + /* + * Rule inferrers can be configured here. They will automatically add + * validation rules to properties of a data object based upon + * the type of the property. + */ + 'rule_inferrers' => [ + SometimesRuleInferrer::class, + NullableRuleInferrer::class, + RequiredRuleInferrer::class, + BuiltInTypesRuleInferrer::class, + AttributesRuleInferrer::class, + ], + + /* + * Normalizers return an array representation of the payload, or null if + * it cannot normalize the payload. The normalizers below are used for + * every data object, unless overridden in a specific data object class. + */ + 'normalizers' => [ + ModelNormalizer::class, + // Spatie\LaravelData\Normalizers\FormRequestNormalizer::class, + ArrayableNormalizer::class, + ObjectNormalizer::class, + ArrayNormalizer::class, + JsonNormalizer::class, + ], + + /* + * Data objects can be wrapped into a key like 'data' when used as a resource, + * this key can be set globally here for all data objects. You can pass in + * `null` if you want to disable wrapping. + */ + 'wrap' => 'data', + + /* + * Adds a specific caster to the Symphony VarDumper component which hides + * some properties from data objects and collections when being dumped + * by `dump` or `dd`. Can be 'enabled', 'disabled' or 'development' + * which will only enable the caster locally. + */ + 'var_dumper_caster_mode' => 'development', + + /* + * It is possible to skip the PHP reflection analysis of data objects + * when running in production. This will speed up the package. You + * can configure where data objects are stored and which cache + * store should be used. + * + * Structures are cached forever as they'll become stale when your + * application is deployed with changes. You can set a duration + * in seconds if you want the cache to clear after a certain + * timeframe. + */ + 'structure_caching' => [ + 'enabled' => true, + 'directories' => [app_path('Data')], + 'cache' => [ + 'store' => env('CACHE_STORE', env('CACHE_DRIVER', 'file')), + 'prefix' => 'laravel-data', + 'duration' => null, + ], + 'reflection_discovery' => [ + 'enabled' => true, + 'base_path' => base_path(), + 'root_namespace' => null, + ], + ], + + /* + * A data object can be validated when created using a factory or when calling the from + * method. By default, only when a request is passed the data is being validated. This + * behaviour can be changed to always validate or to completely disable validation. + */ + 'validation_strategy' => ValidationStrategy::OnlyRequests->value, + + /* + * A data object can map the names of its properties when transforming (output) or when + * creating (input). By default, the package will not map any names. You can set a + * global strategy here, or override it on a specific data object. + */ + 'name_mapping_strategy' => [ + 'input' => null, + 'output' => null, + ], + + /* + * When using an invalid include, exclude, only or except partial, the package will + * throw an exception. You can disable this behaviour by setting this option to true. + */ + 'ignore_invalid_partials' => false, + + /* + * When transforming a nested chain of data objects, the package can end up in an infinite + * loop when including a recursive relationship. The max transformation depth can be + * set as a safety measure to prevent this from happening. When set to null, the + * package will not enforce a maximum depth. + */ + 'max_transformation_depth' => null, + + /* + * When the maximum transformation depth is reached, the package will throw an exception. + * You can disable this behaviour by setting this option to true which will return an + * empty array. + */ + 'throw_when_max_transformation_depth_reached' => true, + + /* + * When using the `make:data` command, the package will use these settings to generate + * the data classes. You can override these settings by passing options to the command. + */ + 'commands' => [ + + /* + * Provides default configuration for the `make:data` command. These settings can be overridden with options + * passed directly to the `make:data` command for generating single Data classes, or if not set they will + * automatically fall back to these defaults. See `php artisan make:data --help` for more information + */ + 'make' => [ + + /* + * The default namespace for generated Data classes. This exists under the application's root namespace, + * so the default 'Data` will end up as '\App\Data', and generated Data classes will be placed in the + * app/Data/ folder. Data classes can live anywhere, but this is where `make:data` will put them. + */ + 'namespace' => 'Data', + + /* + * This suffix will be appended to all data classes generated by make:data, so that they are less likely + * to conflict with other related classes, controllers or models with a similar name without resorting + * to adding an alias for the Data object. Set to a blank string (not null) to disable. + */ + 'suffix' => 'Data', + ], + ], + + /* + * When using Livewire, the package allows you to enable or disable the synths + * these synths will automatically handle the data objects and their + * properties when used in a Livewire component. + */ + 'livewire' => [ + 'enable_synths' => false, + ], +]; diff --git a/config/database.php b/config/database.php index 137ad18ce38..1fc80662a4d 100644 --- a/config/database.php +++ b/config/database.php @@ -1,151 +1,10 @@ env('DB_CONNECTION', 'mysql'), - - /* - |-------------------------------------------------------------------------- - | Database Connections - |-------------------------------------------------------------------------- - | - | Here are each of the database connections setup for your application. - | Of course, examples of configuring each database platform that is - | supported by Laravel is shown below to make development simple. - | - | - | All database work in Laravel is done through the PHP PDO facilities - | so make sure you have the driver for your particular database of - | choice installed on your machine before you begin development. - | - */ - - 'connections' => [ - - 'sqlite' => [ - 'driver' => 'sqlite', - 'url' => env('DATABASE_URL'), - 'database' => env('DB_DATABASE', database_path('database.sqlite')), - 'prefix' => '', - 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), - ], - - 'mysql' => [ - 'driver' => 'mysql', - 'url' => env('DATABASE_URL'), - 'host' => env('DB_HOST', '127.0.0.1'), - 'port' => env('DB_PORT', '3306'), - 'database' => env('DB_DATABASE', 'forge'), - 'username' => env('DB_USERNAME', 'forge'), - 'password' => env('DB_PASSWORD', ''), - 'unix_socket' => env('DB_SOCKET', ''), - 'charset' => 'utf8mb4', - 'collation' => 'utf8mb4_unicode_ci', - 'prefix' => '', - 'prefix_indexes' => true, - 'strict' => true, - 'engine' => null, - 'options' => extension_loaded('pdo_mysql') ? array_filter([ - PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), - ]) : [], - ], - - 'pgsql' => [ - 'driver' => 'pgsql', - 'url' => env('DATABASE_URL'), - 'host' => env('DB_HOST', '127.0.0.1'), - 'port' => env('DB_PORT', '5432'), - 'database' => env('DB_DATABASE', 'forge'), - 'username' => env('DB_USERNAME', 'forge'), - 'password' => env('DB_PASSWORD', ''), - 'charset' => 'utf8', - 'prefix' => '', - 'prefix_indexes' => true, - 'search_path' => 'public', - 'sslmode' => 'prefer', - ], - - 'sqlsrv' => [ - 'driver' => 'sqlsrv', - 'url' => env('DATABASE_URL'), - 'host' => env('DB_HOST', 'localhost'), - 'port' => env('DB_PORT', '1433'), - 'database' => env('DB_DATABASE', 'forge'), - 'username' => env('DB_USERNAME', 'forge'), - 'password' => env('DB_PASSWORD', ''), - 'charset' => 'utf8', - 'prefix' => '', - 'prefix_indexes' => true, - // 'encrypt' => env('DB_ENCRYPT', 'yes'), - // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), - ], - - ], - - /* - |-------------------------------------------------------------------------- - | Migration Repository Table - |-------------------------------------------------------------------------- - | - | This table keeps track of all the migrations that have already run for - | your application. Using this information, we can determine which of - | the migrations on disk haven't actually been run in the database. - | - */ - - 'migrations' => 'migrations', - - /* - |-------------------------------------------------------------------------- - | Redis Databases - |-------------------------------------------------------------------------- - | - | Redis is an open source, fast, and advanced key-value store that also - | provides a richer body of commands than a typical key-value system - | such as APC or Memcached. Laravel makes it easy to dig right in. - | - */ - - 'redis' => [ - - 'client' => env('REDIS_CLIENT', 'phpredis'), - - 'options' => [ - 'cluster' => env('REDIS_CLUSTER', 'redis'), - 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), - ], - - 'default' => [ - 'url' => env('REDIS_URL'), - 'host' => env('REDIS_HOST', '127.0.0.1'), - 'username' => env('REDIS_USERNAME'), - 'password' => env('REDIS_PASSWORD'), - 'port' => env('REDIS_PORT', '6379'), - 'database' => env('REDIS_DB', '0'), - ], - - 'cache' => [ - 'url' => env('REDIS_URL'), - 'host' => env('REDIS_HOST', '127.0.0.1'), - 'username' => env('REDIS_USERNAME'), - 'password' => env('REDIS_PASSWORD'), - 'port' => env('REDIS_PORT', '6379'), - 'database' => env('REDIS_CACHE_DB', '1'), - ], - + 'migrations' => [ + 'table' => 'migrations', + 'update_date_on_publish' => false, // disable to preserve original behavior for existing applications ], ]; diff --git a/config/deployments.php b/config/deployments.php new file mode 100644 index 00000000000..346b9c3ce5d --- /dev/null +++ b/config/deployments.php @@ -0,0 +1,11 @@ + env('DEPLOYMENT_STUCK_AGE', 1440), + + // The number of days to keep deployment history. + // Set to 0 to disable. + 'retention_period' => env('DEPLOYMENT_RETENTION_PERIOD', 90), +]; diff --git a/config/filesystems.php b/config/filesystems.php index e9d9dbdbe8a..580471493e7 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -6,11 +6,6 @@ |-------------------------------------------------------------------------- | Default Filesystem Disk |-------------------------------------------------------------------------- - | - | Here you may specify the default filesystem disk that should be used - | by the framework. The "local" disk, as well as a variety of cloud - | based disks are available to your application. Just store away! - | */ 'default' => env('FILESYSTEM_DISK', 'local'), @@ -20,11 +15,17 @@ | Filesystem Disks |-------------------------------------------------------------------------- | - | Here you may configure as many filesystem "disks" as you wish, and you - | may even configure multiple disks of the same driver. Defaults have - | been set up for each driver as an example of the required values. + | The `artifacts` disk is where a file the operator has nowhere else to host + | lives -- a disk image, or an ISO. It is the panel's answer to "I have a + | file and no CDN": upload it, and the panel serves it over an expiring + | signed URL that a node fetches once, when it first needs it. | - | Supported Drivers: "local", "ftp", "sftp", "s3" + | `serve => true` is what makes those signed URLs work on local disk, so the + | zero-infrastructure default needs no object store at all. An operator who + | outgrows serving multi-gigabyte files from the panel points ARTIFACTS_DISK + | at `s3` and nothing above this file changes -- the panel still mints the + | URL, it just resolves somewhere else. That swap needs + | `league/flysystem-aws-s3-v3`, which is not installed by default. | */ @@ -32,8 +33,10 @@ 'local' => [ 'driver' => 'local', - 'root' => storage_path('app'), + 'root' => storage_path('app/private'), + 'serve' => true, 'throw' => false, + 'report' => false, ], 'public' => [ @@ -42,6 +45,15 @@ 'url' => env('APP_URL').'/storage', 'visibility' => 'public', 'throw' => false, + 'report' => false, + ], + + 'artifacts' => [ + 'driver' => 'local', + 'root' => storage_path('app/artifacts'), + 'serve' => true, + 'throw' => false, + 'report' => false, ], 's3' => [ @@ -54,6 +66,7 @@ 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), 'throw' => false, + 'report' => false, ], ], @@ -62,11 +75,6 @@ |-------------------------------------------------------------------------- | Symbolic Links |-------------------------------------------------------------------------- - | - | Here you may configure the symbolic links that will be created when the - | `storage:link` Artisan command is executed. The array keys should be - | the locations of the links and the values should be their targets. - | */ 'links' => [ diff --git a/config/fortify.php b/config/fortify.php index 358fc33d88a..f22564da14c 100644 --- a/config/fortify.php +++ b/config/fortify.php @@ -1,6 +1,7 @@ RouteServiceProvider::HOME, + 'home' => AppServiceProvider::HOME, /* |-------------------------------------------------------------------------- @@ -131,16 +132,19 @@ */ 'features' => [ - // Features::registration(), - // Features::resetPasswords(), - // Features::emailVerification(), - // Features::updateProfileInformation(), - // Features::updatePasswords(), - // Features::twoFactorAuthentication([ - // 'confirm' => true, - // 'confirmPassword' => true, - // // 'window' => 0, - // ]), + Features::twoFactorAuthentication([ + // Require a generated code before two factor counts as enabled. + // Enabling mints the secret as soon as the setup dialog opens, so + // with this off a user who opened it and walked away — or who never + // finished scanning — still had `two_factor_secret` set, which is + // all `hasEnabledTwoFactorAuthentication()` looked at. Their next + // login then demanded a code from an authenticator they never + // configured. With confirm on, an unfinished setup leaves + // `two_factor_confirmed_at` null and is simply inert. + 'confirm' => true, + 'confirmPassword' => true, + 'window' => 30, + ]), ], ]; diff --git a/config/hashing.php b/config/hashing.php deleted file mode 100644 index bcd3be4c28a..00000000000 --- a/config/hashing.php +++ /dev/null @@ -1,52 +0,0 @@ - 'bcrypt', - - /* - |-------------------------------------------------------------------------- - | Bcrypt Options - |-------------------------------------------------------------------------- - | - | Here you may specify the configuration options that should be used when - | passwords are hashed using the Bcrypt algorithm. This will allow you - | to control the amount of time it takes to hash the given password. - | - */ - - 'bcrypt' => [ - 'rounds' => env('BCRYPT_ROUNDS', 10), - ], - - /* - |-------------------------------------------------------------------------- - | Argon Options - |-------------------------------------------------------------------------- - | - | Here you may specify the configuration options that should be used when - | passwords are hashed using the Argon algorithm. These will allow you - | to control the amount of time it takes to hash the given password. - | - */ - - 'argon' => [ - 'memory' => 65536, - 'threads' => 1, - 'time' => 4, - ], - -]; diff --git a/config/invites.php b/config/invites.php new file mode 100644 index 00000000000..c0985ec424d --- /dev/null +++ b/config/invites.php @@ -0,0 +1,16 @@ + (int) env('INVITE_TTL_DAYS', 7), +]; diff --git a/config/logging.php b/config/logging.php deleted file mode 100644 index c44d27639aa..00000000000 --- a/config/logging.php +++ /dev/null @@ -1,131 +0,0 @@ - env('LOG_CHANNEL', 'stack'), - - /* - |-------------------------------------------------------------------------- - | Deprecations Log Channel - |-------------------------------------------------------------------------- - | - | This option controls the log channel that should be used to log warnings - | regarding deprecated PHP and library features. This allows you to get - | your application ready for upcoming major versions of dependencies. - | - */ - - 'deprecations' => [ - 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), - 'trace' => false, - ], - - /* - |-------------------------------------------------------------------------- - | Log Channels - |-------------------------------------------------------------------------- - | - | Here you may configure the log channels for your application. Out of - | the box, Laravel uses the Monolog PHP logging library. This gives - | you a variety of powerful log handlers / formatters to utilize. - | - | Available Drivers: "single", "daily", "slack", "syslog", - | "errorlog", "monolog", - | "custom", "stack" - | - */ - - 'channels' => [ - 'stack' => [ - 'driver' => 'stack', - 'channels' => ['single'], - 'ignore_exceptions' => false, - ], - - 'single' => [ - 'driver' => 'single', - 'path' => storage_path('logs/laravel.log'), - 'level' => env('LOG_LEVEL', 'debug'), - 'replace_placeholders' => true, - ], - - 'daily' => [ - 'driver' => 'daily', - 'path' => storage_path('logs/laravel.log'), - 'level' => env('LOG_LEVEL', 'debug'), - 'days' => 14, - 'replace_placeholders' => true, - ], - - 'slack' => [ - 'driver' => 'slack', - 'url' => env('LOG_SLACK_WEBHOOK_URL'), - 'username' => 'Laravel Log', - 'emoji' => ':boom:', - 'level' => env('LOG_LEVEL', 'critical'), - 'replace_placeholders' => true, - ], - - 'papertrail' => [ - 'driver' => 'monolog', - 'level' => env('LOG_LEVEL', 'debug'), - 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), - 'handler_with' => [ - 'host' => env('PAPERTRAIL_URL'), - 'port' => env('PAPERTRAIL_PORT'), - 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), - ], - 'processors' => [PsrLogMessageProcessor::class], - ], - - 'stderr' => [ - 'driver' => 'monolog', - 'level' => env('LOG_LEVEL', 'debug'), - 'handler' => StreamHandler::class, - 'formatter' => env('LOG_STDERR_FORMATTER'), - 'with' => [ - 'stream' => 'php://stderr', - ], - 'processors' => [PsrLogMessageProcessor::class], - ], - - 'syslog' => [ - 'driver' => 'syslog', - 'level' => env('LOG_LEVEL', 'debug'), - 'facility' => LOG_USER, - 'replace_placeholders' => true, - ], - - 'errorlog' => [ - 'driver' => 'errorlog', - 'level' => env('LOG_LEVEL', 'debug'), - 'replace_placeholders' => true, - ], - - 'null' => [ - 'driver' => 'monolog', - 'handler' => NullHandler::class, - ], - - 'emergency' => [ - 'path' => storage_path('logs/laravel.log'), - ], - ], - -]; diff --git a/config/mail.php b/config/mail.php index 542d98c37c4..77815a61977 100644 --- a/config/mail.php +++ b/config/mail.php @@ -2,123 +2,13 @@ return [ - /* - |-------------------------------------------------------------------------- - | Default Mailer - |-------------------------------------------------------------------------- - | - | This option controls the default mailer that is used to send any email - | messages sent by your application. Alternative mailers may be setup - | and used as needed; however, this mailer will be used by default. - | - */ - - 'default' => env('MAIL_MAILER', 'smtp'), - - /* - |-------------------------------------------------------------------------- - | Mailer Configurations - |-------------------------------------------------------------------------- - | - | Here you may configure all of the mailers used by your application plus - | their respective settings. Several examples have been configured for - | you and you are free to add your own as your application requires. - | - | Laravel supports a variety of mail "transport" drivers to be used while - | sending an e-mail. You will specify which one you are using for your - | mailers below. You are free to add additional mailers as required. - | - | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", - | "postmark", "log", "array", "failover" - | - */ - 'mailers' => [ - 'smtp' => [ - 'transport' => 'smtp', - 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), - 'port' => env('MAIL_PORT', 587), - 'encryption' => env('MAIL_ENCRYPTION', 'tls'), - 'username' => env('MAIL_USERNAME'), - 'password' => env('MAIL_PASSWORD'), - 'timeout' => null, - 'local_domain' => env('MAIL_EHLO_DOMAIN'), - ], - - 'ses' => [ - 'transport' => 'ses', - ], - 'mailgun' => [ 'transport' => 'mailgun', // 'client' => [ // 'timeout' => 5, // ], ], - - 'postmark' => [ - 'transport' => 'postmark', - // 'client' => [ - // 'timeout' => 5, - // ], - ], - - 'sendmail' => [ - 'transport' => 'sendmail', - 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), - ], - - 'log' => [ - 'transport' => 'log', - 'channel' => env('MAIL_LOG_CHANNEL'), - ], - - 'array' => [ - 'transport' => 'array', - ], - - 'failover' => [ - 'transport' => 'failover', - 'mailers' => [ - 'smtp', - 'log', - ], - ], - ], - - /* - |-------------------------------------------------------------------------- - | Global "From" Address - |-------------------------------------------------------------------------- - | - | You may wish for all e-mails sent by your application to be sent from - | the same address. Here, you may specify a name and address that is - | used globally for all e-mails that are sent by your application. - | - */ - - 'from' => [ - 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), - 'name' => env('MAIL_FROM_NAME', 'Example'), - ], - - /* - |-------------------------------------------------------------------------- - | Markdown Mail Settings - |-------------------------------------------------------------------------- - | - | If you are using Markdown based email rendering, you may configure your - | theme and component paths here, allowing you to customize the design - | of the emails. Or, you may simply stick with the Laravel defaults! - | - */ - - 'markdown' => [ - 'theme' => 'default', - - 'paths' => [ - resource_path('views/vendor/mail'), - ], ], ]; diff --git a/config/metrics.php b/config/metrics.php new file mode 100644 index 00000000000..a287806a151 --- /dev/null +++ b/config/metrics.php @@ -0,0 +1,12 @@ + [ + 'url' => env('VICTORIAMETRICS_URL'), + ], +]; diff --git a/config/oauth.php b/config/oauth.php new file mode 100644 index 00000000000..471101787d1 --- /dev/null +++ b/config/oauth.php @@ -0,0 +1,69 @@ +"); a + | provider is only surfaced/usable when its `enabled` flag is true AND the + | matching `config/services.php` block has a client id + secret. + */ + 'providers' => [ + 'google' => [ + 'enabled' => (bool) env('OAUTH_GOOGLE_ENABLED', false), + 'label' => 'Google', + ], + 'github' => [ + 'enabled' => (bool) env('OAUTH_GITHUB_ENABLED', false), + 'label' => 'GitHub', + ], + 'gitlab' => [ + 'enabled' => (bool) env('OAUTH_GITLAB_ENABLED', false), + 'label' => 'GitLab', + ], + // Generic OpenID Connect against any standards-compliant IdP. The button label is + // operator-set (e.g. "Keycloak", "Okta", "Company SSO") since there's no fixed brand. + 'oidc' => [ + 'enabled' => (bool) env('OAUTH_OIDC_ENABLED', false), + 'label' => env('OAUTH_OIDC_LABEL', 'OpenID Connect'), + ], + ], + + /* + | When true, a successful sign-in from a provider whose identity does not + | match any existing user (by connection or verified email) provisions a + | brand-new, non-admin Convoy account. Off by default: most panels want a + | closed door where only pre-existing users may federate. Auto-provisioned + | users never receive `root_admin`. + */ + 'registration' => (bool) env('OAUTH_REGISTRATION', false), + + /* + | When true, a provider identity whose verified email matches an existing + | Convoy user is linked to that account on first sign-in (so an operator + | can pre-create users and let them "Continue with Google" without an + | explicit link step). Only honoured when the provider asserts the email + | is verified. Off flips to "explicit link only" (users must connect the + | provider from their account security page while logged in). + */ + 'link_by_verified_email' => (bool) env('OAUTH_LINK_BY_VERIFIED_EMAIL', true), + +]; diff --git a/config/passkeys.php b/config/passkeys.php new file mode 100644 index 00000000000..89a266a32e5 --- /dev/null +++ b/config/passkeys.php @@ -0,0 +1,56 @@ + '/', + + /* + * These classes are responsible for performing core tasks regarding passkeys. + * Convoy-specific behavior is kept in thin subclasses: + * - option generators require user verification for every ceremony. + * - store_passkey: keeps our curated error-code exceptions (HasErrorCode). + * - configure_ceremony_step_manager_factory: canary/localhost origin handling. + * The rest use the package defaults. + */ + 'actions' => [ + 'generate_passkey_register_options' => GeneratePasskeyRegisterOptionsAction::class, + 'store_passkey' => StorePasskeyAction::class, + 'generate_passkey_authentication_options' => GeneratePasskeyAuthenticationOptionsAction::class, + 'find_passkey' => FindPasskeyToAuthenticateAction::class, + 'configure_ceremony_step_manager_factory' => ConfigureCeremonyStepManagerFactoryAction::class, + ], + + /* + * These properties will be used to generate the passkey. + */ + 'relying_party' => [ + 'name' => config('app.name'), + 'id' => parse_url(config('app.url'), PHP_URL_HOST), + 'icon' => null, + ], + + /* + * The models used by the package. + * + * `passkey` points at our thin subclass that keeps the existing `user_id` + * schema (via User::passkeys()) and the `id` route key. + */ + 'models' => [ + 'passkey' => Passkey::class, + 'authenticatable' => User::class, + ], +]; diff --git a/config/queue.php b/config/queue.php deleted file mode 100644 index 25ea5a81935..00000000000 --- a/config/queue.php +++ /dev/null @@ -1,93 +0,0 @@ - env('QUEUE_CONNECTION', 'sync'), - - /* - |-------------------------------------------------------------------------- - | Queue Connections - |-------------------------------------------------------------------------- - | - | Here you may configure the connection information for each server that - | is used by your application. A default configuration has been added - | for each back-end shipped with Laravel. You are free to add more. - | - | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" - | - */ - - 'connections' => [ - - 'sync' => [ - 'driver' => 'sync', - ], - - 'database' => [ - 'driver' => 'database', - 'table' => 'jobs', - 'queue' => 'default', - 'retry_after' => 90, - 'after_commit' => false, - ], - - 'beanstalkd' => [ - 'driver' => 'beanstalkd', - 'host' => 'localhost', - 'queue' => 'default', - 'retry_after' => 90, - 'block_for' => 0, - 'after_commit' => false, - ], - - 'sqs' => [ - 'driver' => 'sqs', - 'key' => env('AWS_ACCESS_KEY_ID'), - 'secret' => env('AWS_SECRET_ACCESS_KEY'), - 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), - 'queue' => env('SQS_QUEUE', 'default'), - 'suffix' => env('SQS_SUFFIX'), - 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), - 'after_commit' => false, - ], - - 'redis' => [ - 'driver' => 'redis', - 'connection' => 'default', - 'queue' => env('REDIS_QUEUE', 'default'), - 'retry_after' => 90, - 'block_for' => null, - 'after_commit' => false, - ], - - ], - - /* - |-------------------------------------------------------------------------- - | Failed Queue Jobs - |-------------------------------------------------------------------------- - | - | These options configure the behavior of failed queue job logging so you - | can control which database and table are used to store the jobs that - | have failed. You may change them to any database / table you wish. - | - */ - - 'failed' => [ - 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), - 'database' => env('DB_CONNECTION', 'mysql'), - 'table' => 'failed_jobs', - ], - -]; diff --git a/config/sanctum.php b/config/sanctum.php index fedd85c1503..935b5cbad4d 100644 --- a/config/sanctum.php +++ b/config/sanctum.php @@ -1,5 +1,7 @@ explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( - '%s%s', - 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', - Sanctum::currentApplicationUrlWithPort() - ))), + 'stateful' => explode( + ',', + env( + 'SANCTUM_STATEFUL_DOMAINS', + sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort(), + ), + ), + ), /* |-------------------------------------------------------------------------- @@ -60,8 +68,8 @@ */ 'middleware' => [ - 'verify_csrf_token' => Convoy\Http\Middleware\VerifyCsrfToken::class, - 'encrypt_cookies' => Convoy\Http\Middleware\EncryptCookies::class, + 'validate_csrf_token' => ValidateCsrfToken::class, + 'encrypt_cookies' => EncryptCookies::class, ], ]; diff --git a/config/scout.php b/config/scout.php deleted file mode 100644 index 5c8b7d20f11..00000000000 --- a/config/scout.php +++ /dev/null @@ -1,137 +0,0 @@ - env('SCOUT_DRIVER', 'algolia'), - - /* - |-------------------------------------------------------------------------- - | Index Prefix - |-------------------------------------------------------------------------- - | - | Here you may specify a prefix that will be applied to all search index - | names used by Scout. This prefix may be useful if you have multiple - | "tenants" or applications sharing the same search infrastructure. - | - */ - - 'prefix' => env('SCOUT_PREFIX', ''), - - /* - |-------------------------------------------------------------------------- - | Queue Data Syncing - |-------------------------------------------------------------------------- - | - | This option allows you to control if the operations that sync your data - | with your search engines are queued. When this is set to "true" then - | all automatic data syncing will get queued for better performance. - | - */ - - 'queue' => env('SCOUT_QUEUE', false), - - /* - |-------------------------------------------------------------------------- - | Database Transactions - |-------------------------------------------------------------------------- - | - | This configuration option determines if your data will only be synced - | with your search indexes after every open database transaction has - | been committed, thus preventing any discarded data from syncing. - | - */ - - 'after_commit' => false, - - /* - |-------------------------------------------------------------------------- - | Chunk Sizes - |-------------------------------------------------------------------------- - | - | These options allow you to control the maximum chunk size when you are - | mass importing data into the search engine. This allows you to fine - | tune each of these chunk sizes based on the power of the servers. - | - */ - - 'chunk' => [ - 'searchable' => 500, - 'unsearchable' => 500, - ], - - /* - |-------------------------------------------------------------------------- - | Soft Deletes - |-------------------------------------------------------------------------- - | - | This option allows to control whether to keep soft deleted records in - | the search indexes. Maintaining soft deleted records can be useful - | if your application still needs to search for the records later. - | - */ - - 'soft_delete' => false, - - /* - |-------------------------------------------------------------------------- - | Identify User - |-------------------------------------------------------------------------- - | - | This option allows you to control whether to notify the search engine - | of the user performing the search. This is sometimes useful if the - | engine supports any analytics based on this application's users. - | - | Supported engines: "algolia" - | - */ - - 'identify' => env('SCOUT_IDENTIFY', false), - - /* - |-------------------------------------------------------------------------- - | Algolia Configuration - |-------------------------------------------------------------------------- - | - | Here you may configure your Algolia settings. Algolia is a cloud hosted - | search engine which works great with Scout out of the box. Just plug - | in your application ID and admin API key to get started searching. - | - */ - - 'algolia' => [ - 'id' => env('ALGOLIA_APP_ID', ''), - 'secret' => env('ALGOLIA_SECRET', ''), - ], - - /* - |-------------------------------------------------------------------------- - | MeiliSearch Configuration - |-------------------------------------------------------------------------- - | - | Here you may configure your MeiliSearch settings. MeiliSearch is an open - | source search engine with minimal configuration. Below, you can state - | the host and key information for your own MeiliSearch installation. - | - | See: https://docs.meilisearch.com/guides/advanced_guides/configuration.html - | - */ - - 'meilisearch' => [ - 'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'), - 'key' => env('MEILISEARCH_KEY', null), - ], - -]; diff --git a/config/services.php b/config/services.php index 0ace530e8d2..cce90956a08 100644 --- a/config/services.php +++ b/config/services.php @@ -2,18 +2,6 @@ return [ - /* - |-------------------------------------------------------------------------- - | Third Party Services - |-------------------------------------------------------------------------- - | - | This file is for storing the credentials for third party services such - | as Mailgun, Postmark, AWS and more. This file provides the de facto - | location for this type of information, allowing packages to have - | a conventional file to locate the various service credentials. - | - */ - 'mailgun' => [ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), @@ -21,14 +9,49 @@ 'scheme' => 'https', ], - 'postmark' => [ - 'token' => env('POSTMARK_TOKEN'), + /* + | OAuth / OIDC Relying-Party providers (see config/oauth.php). `redirect` + | is a path that Socialite resolves against APP_URL; it must match the + | `auth.oauth.callback` route and the URI registered with the provider. + */ + 'google' => [ + 'client_id' => env('OAUTH_GOOGLE_CLIENT_ID'), + 'client_secret' => env('OAUTH_GOOGLE_CLIENT_SECRET'), + 'redirect' => env('OAUTH_GOOGLE_REDIRECT_URI', '/api/auth/oauth/google/callback'), + ], + + 'github' => [ + 'client_id' => env('OAUTH_GITHUB_CLIENT_ID'), + 'client_secret' => env('OAUTH_GITHUB_CLIENT_SECRET'), + 'redirect' => env('OAUTH_GITHUB_REDIRECT_URI', '/api/auth/oauth/github/callback'), + ], + + 'gitlab' => [ + 'client_id' => env('OAUTH_GITLAB_CLIENT_ID'), + 'client_secret' => env('OAUTH_GITLAB_CLIENT_SECRET'), + 'redirect' => env('OAUTH_GITLAB_REDIRECT_URI', '/api/auth/oauth/gitlab/callback'), ], - 'ses' => [ - 'key' => env('AWS_ACCESS_KEY_ID'), - 'secret' => env('AWS_SECRET_ACCESS_KEY'), - 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + /* + | Generic OpenID Connect. `base_url` is the IdP issuer; the authorize/token/userinfo + | endpoints are discovered from `{base_url}/.well-known/openid-configuration`, so for a + | standards-compliant IdP (Keycloak, Authentik, Okta, Auth0, Azure AD, …) an operator + | only needs the issuer plus a client id/secret. The three *_url overrides pin an + | endpoint explicitly for IdPs whose discovery is non-standard. `scopes` (comma list) + | overrides the requested scopes; `openid` is always included regardless. + */ + 'oidc' => [ + 'client_id' => env('OAUTH_OIDC_CLIENT_ID'), + 'client_secret' => env('OAUTH_OIDC_CLIENT_SECRET'), + 'redirect' => env('OAUTH_OIDC_REDIRECT_URI', '/api/auth/oauth/oidc/callback'), + 'base_url' => env('OAUTH_OIDC_BASE_URL'), + 'scopes' => array_values(array_filter(array_map( + 'trim', + explode(',', (string) env('OAUTH_OIDC_SCOPES', 'profile,email')), + ))), + 'auth_url' => env('OAUTH_OIDC_AUTH_URL'), + 'token_url' => env('OAUTH_OIDC_TOKEN_URL'), + 'userinfo_url' => env('OAUTH_OIDC_USERINFO_URL'), ], ]; diff --git a/config/session.php b/config/session.php deleted file mode 100644 index 8fed97c0141..00000000000 --- a/config/session.php +++ /dev/null @@ -1,201 +0,0 @@ - env('SESSION_DRIVER', 'file'), - - /* - |-------------------------------------------------------------------------- - | Session Lifetime - |-------------------------------------------------------------------------- - | - | Here you may specify the number of minutes that you wish the session - | to be allowed to remain idle before it expires. If you want them - | to immediately expire on the browser closing, set that option. - | - */ - - 'lifetime' => env('SESSION_LIFETIME', 120), - - 'expire_on_close' => false, - - /* - |-------------------------------------------------------------------------- - | Session Encryption - |-------------------------------------------------------------------------- - | - | This option allows you to easily specify that all of your session data - | should be encrypted before it is stored. All encryption will be run - | automatically by Laravel and you can use the Session like normal. - | - */ - - 'encrypt' => false, - - /* - |-------------------------------------------------------------------------- - | Session File Location - |-------------------------------------------------------------------------- - | - | When using the native session driver, we need a location where session - | files may be stored. A default has been set for you but a different - | location may be specified. This is only needed for file sessions. - | - */ - - 'files' => storage_path('framework/sessions'), - - /* - |-------------------------------------------------------------------------- - | Session Database Connection - |-------------------------------------------------------------------------- - | - | When using the "database" or "redis" session drivers, you may specify a - | connection that should be used to manage these sessions. This should - | correspond to a connection in your database configuration options. - | - */ - - 'connection' => env('SESSION_CONNECTION'), - - /* - |-------------------------------------------------------------------------- - | Session Database Table - |-------------------------------------------------------------------------- - | - | When using the "database" session driver, you may specify the table we - | should use to manage the sessions. Of course, a sensible default is - | provided for you; however, you are free to change this as needed. - | - */ - - 'table' => 'sessions', - - /* - |-------------------------------------------------------------------------- - | Session Cache Store - |-------------------------------------------------------------------------- - | - | While using one of the framework's cache driven session backends you may - | list a cache store that should be used for these sessions. This value - | must match with one of the application's configured cache "stores". - | - | Affects: "apc", "dynamodb", "memcached", "redis" - | - */ - - 'store' => env('SESSION_STORE'), - - /* - |-------------------------------------------------------------------------- - | Session Sweeping Lottery - |-------------------------------------------------------------------------- - | - | Some session drivers must manually sweep their storage location to get - | rid of old sessions from storage. Here are the chances that it will - | happen on a given request. By default, the odds are 2 out of 100. - | - */ - - 'lottery' => [2, 100], - - /* - |-------------------------------------------------------------------------- - | Session Cookie Name - |-------------------------------------------------------------------------- - | - | Here you may change the name of the cookie used to identify a session - | instance by ID. The name specified here will get used every time a - | new session cookie is created by the framework for every driver. - | - */ - - 'cookie' => env( - 'SESSION_COOKIE', - Str::slug(env('APP_NAME', 'laravel'), '_').'_session' - ), - - /* - |-------------------------------------------------------------------------- - | Session Cookie Path - |-------------------------------------------------------------------------- - | - | The session cookie path determines the path for which the cookie will - | be regarded as available. Typically, this will be the root path of - | your application but you are free to change this when necessary. - | - */ - - 'path' => '/', - - /* - |-------------------------------------------------------------------------- - | Session Cookie Domain - |-------------------------------------------------------------------------- - | - | Here you may change the domain of the cookie used to identify a session - | in your application. This will determine which domains the cookie is - | available to in your application. A sensible default has been set. - | - */ - - 'domain' => env('SESSION_DOMAIN'), - - /* - |-------------------------------------------------------------------------- - | HTTPS Only Cookies - |-------------------------------------------------------------------------- - | - | By setting this option to true, session cookies will only be sent back - | to the server if the browser has a HTTPS connection. This will keep - | the cookie from being sent to you when it can't be done securely. - | - */ - - 'secure' => env('SESSION_SECURE_COOKIE'), - - /* - |-------------------------------------------------------------------------- - | HTTP Access Only - |-------------------------------------------------------------------------- - | - | Setting this value to true will prevent JavaScript from accessing the - | value of the cookie and the cookie will only be accessible through - | the HTTP protocol. You are free to modify this option if needed. - | - */ - - 'http_only' => true, - - /* - |-------------------------------------------------------------------------- - | Same-Site Cookies - |-------------------------------------------------------------------------- - | - | This option determines how your cookies behave when cross-site requests - | take place, and can be used to mitigate CSRF attacks. By default, we - | will set this value to "lax" since this is a secure default value. - | - | Supported: "lax", "strict", "none", null - | - */ - - 'same_site' => 'lax', - -]; diff --git a/config/settings.php b/config/settings.php new file mode 100644 index 00000000000..4ae713a0065 --- /dev/null +++ b/config/settings.php @@ -0,0 +1,119 @@ + [ + AccountSettings::class, + AnchorSettings::class, + AuditSettings::class, + BandwidthSettings::class, + MailSettings::class, + ], + + /* + * The path where the settings classes will be created. + */ + 'setting_class_path' => app_path('Settings'), + + /* + * In these directories settings migrations will be stored and ran when migrating. A settings + * migration created via the make:settings-migration command will be stored in the first path or + * a custom defined path when running the command. + */ + 'migrations_paths' => [ + database_path('settings'), + ], + + /* + * When no repository was set for a settings class the following repository + * will be used for loading and saving settings. + */ + 'default_repository' => 'database', + + /* + * Settings will be stored and loaded from these repositories. + */ + 'repositories' => [ + 'database' => [ + 'type' => DatabaseSettingsRepository::class, + 'model' => null, + 'table' => null, + 'connection' => null, + ], + 'redis' => [ + 'type' => RedisSettingsRepository::class, + 'connection' => null, + 'prefix' => null, + ], + ], + + /* + * The encoder and decoder will determine how settings are stored and + * retrieved in the database. By default, `json_encode` and `json_decode` + * are used. + */ + 'encoder' => null, + 'decoder' => null, + + /* + * The contents of settings classes can be cached through your application, + * settings will be stored within a provided Laravel store and can have an + * additional prefix. + * + * Enabled by default: on a cache hit no repository/database calls are made, + * and the cache is invalidated automatically whenever a settings class is + * saved. See docs/bandwidth-rate-limiting-plan.md §5.3. + */ + 'cache' => [ + 'enabled' => (bool) env('SETTINGS_CACHE_ENABLED', true), + 'store' => null, + 'prefix' => null, + 'ttl' => null, + + /* + * When enabled, uses Laravel's memoized cache driver (requires Laravel 12.9+) + * to keep resolved values in memory during a single request. + */ + 'memo' => env('SETTINGS_CACHE_MEMO', false), + ], + + /* + * These global casts will be automatically used whenever a property within + * your settings class isn't a default PHP type. + */ + 'global_casts' => [ + DateTimeInterface::class => DateTimeInterfaceCast::class, + DateTimeZone::class => DateTimeZoneCast::class, + Data::class => DataCast::class, + ], + + /* + * The package will look for settings in these paths and automatically + * register them. + */ + 'auto_discover_settings' => [ + app_path('Settings'), + ], + + /* + * Automatically discovered settings classes can be cached, so they don't + * need to be searched each time the application boots up. + */ + 'discovered_settings_cache_path' => base_path('bootstrap/cache'), +]; diff --git a/config/sso.php b/config/sso.php new file mode 100644 index 00000000000..46bd42bcac7 --- /dev/null +++ b/config/sso.php @@ -0,0 +1,25 @@ + (int) env('SSO_LINK_TTL', 60), + + /* + | The log channel every successful SSO consumption is written to. SSO bypasses password/2FA, + | so each login is audited. Defaults to the application's default channel; point it at a + | dedicated channel (e.g. a separate file) if you want an isolated audit trail. + */ + 'audit_channel' => env('SSO_AUDIT_CHANNEL', env('LOG_CHANNEL', 'stack')), +]; diff --git a/config/trustedproxy.php b/config/trustedproxy.php new file mode 100644 index 00000000000..9d94fecadca --- /dev/null +++ b/config/trustedproxy.php @@ -0,0 +1,7 @@ + env('TRUSTED_PROXIES'), +]; diff --git a/config/view.php b/config/view.php deleted file mode 100644 index 22b8a18d325..00000000000 --- a/config/view.php +++ /dev/null @@ -1,36 +0,0 @@ - [ - resource_path('views'), - ], - - /* - |-------------------------------------------------------------------------- - | Compiled View Path - |-------------------------------------------------------------------------- - | - | This option determines where all the compiled Blade templates will be - | stored for your application. Typically, this is within the storage - | directory. However, as usual, you are free to change this value. - | - */ - - 'compiled' => env( - 'VIEW_COMPILED_PATH', - realpath(storage_path('framework/views')) - ), - -]; diff --git a/crowdin.yml b/crowdin.yml deleted file mode 100644 index 766590747cc..00000000000 --- a/crowdin.yml +++ /dev/null @@ -1,4 +0,0 @@ -preserve_hierarchy: true -files: - - source: /lang/en_US/**/*.php - translation: /lang/%locale_with_underscore%/**/%original_file_name% diff --git a/database/cutover/RUNBOOK.md b/database/cutover/RUNBOOK.md new file mode 100644 index 00000000000..750466bfc0a --- /dev/null +++ b/database/cutover/RUNBOOK.md @@ -0,0 +1,112 @@ +# v4 → v5 production cutover runbook + +Moves a live **v4 (MySQL 8.0)** database onto **v5 (Postgres 17)**. This is a +one-time, operator-run cutover with a maintenance window — **not** a rolling +upgrade. Two hard changes stack: + +1. **Engine conversion** MySQL → Postgres (data lives in MySQL; v5 runs on + Postgres). `artisan migrate` never moves data between engines, so a + dedicated tool (**pgloader**) copies + type-converts the rows first. +2. **24 breaking rename migrations** (`address_pools`→`address_block_groups`, + `ip_addresses`→`addresses`, `address`→`ip`, nodes `name`↔`cluster`, + `secret`→`token_secret`, templates/deployments restructuring, …). These are + ordinary Laravel migrations and run **after** the data is in Postgres. + +So the order is always: **pgloader (engine) → `artisan migrate` (schema)**. + +## Impact on users + +- **End customers' VMs keep running** — Proxmox and the workloads are separate + from the panel DB. Only *panel access* is down during the window. +- **The operator** runs this once, following the steps below. +- **Fresh v5 installs need none of this** — they start on Postgres already. + +## Confidence: the engine step is validated + +`database/cutover/verify.sh` proves the pgloader conversion is lossless on the +real application schema: it seeds a MySQL copy, runs the pgloader recipe into a +scratch Postgres DB, and asserts exact per-table `COUNT(*)` equality plus +per-row content checks of the conversion-risky types (tinyint→boolean, bigint, +JSON). Run it any time — it is fully self-contained and never touches dev data: + +```bash +bash database/cutover/verify.sh # → RESULT: PASS +``` + +The pgloader recipe itself is `database/cutover/v4-to-v5.load` (credential- +free template; connection URLs are injected at run time). + +> **Host-arch caveat.** pgloader ships as an amd64-only image (`dimitri/pgloader`) +> and is an SBCL/Lisp binary, so it runs on x86_64 hosts or under macOS Docker +> Desktop's Rosetta 2 — but **not** under Linux qemu-user emulation, where SBCL +> segfaults. On an arm64 Linux host (some CI/sandbox environments) `verify.sh` +> detects this and tells you to run on an x86_64 / macOS host or set +> `PGLOADER_IMAGE` to a native-arch pgloader. Use a current pgloader (>= 3.6.9): +> Debian's older package trips MySQL 8.0's collation IDs +> ("N fell through ECASE expression"). The real cutover has the same requirement — +> run pgloader where amd64 executes (your Mac works) or with a native build. + +## Cutover procedure + +> Rehearse the whole thing against a **restored copy of prod** first (see "Dry +> run"), and repeat until clean, before touching real prod. + +1. **Announce + enter maintenance mode.** Stop the app, Horizon, and the + scheduler so nothing writes to MySQL mid-copy. +2. **Full MySQL backup** — the rollback anchor. `mysqldump --single-transaction + --routines --triggers > v4-prod-$(date +%F).sql`. Verify it restores. +3. **Provision the empty Postgres 17 target** and an empty database. +4. **Run pgloader** (engine conversion). Render the recipe with real + connection strings and run it (the harness shows the exact form): + ```bash + sed -e "s|\${MYSQL_URL}|mysql://USER:PASS@MYSQLHOST/DB|" \ + -e "s|\${PG_URL}|postgresql://USER:PASS@PGHOST/DB|" \ + database/cutover/v4-to-v5.load > /tmp/cutover.load + pgloader /tmp/cutover.load + ``` + pgloader recreates the v4 tables in Postgres, converts types, copies rows, + and rebuilds indexes/PKs/FKs/sequences. It also copies the `migrations` + table, so Laravel knows exactly which migrations prod had already applied. +5. **Point v5 at Postgres** (`.env`: `DB_CONNECTION=pgsql`, host/db/creds). +6. **Apply the rename migrations.** First preview exactly what will run + (`php artisan migrate:status` — everything prod already ran should show + *Ran*, only the v5 renames *Pending*), then `php artisan migrate --force`. + `--force` only skips the interactive "you're in production" confirmation so + the command runs unattended — it does **not** change what the migrations do. + The real safety here is step 2's backup and the dry run, not that prompt. + Only the pending migrations (the v5 renames) execute, on the converted data. +7. **Smoke test** — run the Phase-1 feature suite / manual happy-path against + the migrated DB (IPAM, nodes, templates, servers, backups). Spot-check row + counts against the pre-cutover backup. +8. **Exit maintenance mode.** + +## Rollback + +Until step 8, rollback is: point `.env` back at the (untouched) MySQL, restart +the v4 app, drop the Postgres target. The MySQL source is only ever *read* by +pgloader, so it remains a valid rollback target the entire time. Keep the step-2 +dump regardless. + +## Dry run (required before real cutover) + +Restore a prod snapshot into a scratch MySQL, run steps 4–7 against it, and diff +row counts / spot-check IPAM + node + template + server records against the +source. Repeat until clean. `verify.sh` automates the engine-conversion half of +this on synthetic data; the dry run repeats it on real prod-shaped data. + +## Known cross-engine gotchas + +- **`renameColumn('x','x')` no-ops**: MySQL tolerates them, Postgres rejects + them. One was already found + fixed in + `2024_10_10_033133_update_backup_snapshot_limit_columns_on_servers_table.php`. + Audit any new migration for the same pattern before cutover. +- **Booleans**: MySQL `tinyint(1)` → Postgres `boolean`. Handled by the CAST + rule in the pgloader recipe (Laravel's Postgres schema expects real booleans). +- **Timestamps**: converted to `timestamptz`; confirm the app treats stored + times as UTC (it does). +- **Reconcile the maintenance line's newer commits** (forward-port) before + cutover so prod users don't regress on v4 fixes made since the merge-base. + Done through v4.6.1 in `3ef53e37`, which merged everything the 4.x line had + that `next` did not. The branch this refers to was `develop`, then `main`, + and is now `4.x`: anything landed or tagged there after v4.6.1 needs the + same treatment before a cutover ships. diff --git a/database/cutover/v4-to-v5.load b/database/cutover/v4-to-v5.load new file mode 100644 index 00000000000..76d91b9986d --- /dev/null +++ b/database/cutover/v4-to-v5.load @@ -0,0 +1,39 @@ +-- +-- pgloader recipe: cross-engine copy of a live v4 database from MySQL 8.0 into +-- Postgres 17, as the first step of the v5 cutover. After this runs, +-- `php artisan migrate` applies the v5 rename migrations on the converted data. +-- +-- Connection strings are templated (${...}) and filled in by the runbook / +-- harness (database/cutover/verify.sh) so no credentials live in the repo. +-- +-- Cast rules exist to reproduce the types Laravel's Postgres schema expects, +-- which pgloader would not infer from MySQL's storage types alone: +-- * tinyint(1) -> boolean (Laravel booleans; MySQL has no bool type) +-- * datetime/timestamp -> timestamptz (Laravel stores UTC timestamps) +-- * json -> json (match Laravel's ->json(); pgloader would +-- otherwise pick jsonb) +-- +LOAD DATABASE + FROM ${MYSQL_URL} + INTO ${PG_URL} + + WITH include drop, + create tables, + create indexes, + reset sequences, + foreign keys, + workers = 4, + concurrency = 1 + + SET PostgreSQL PARAMETERS + maintenance_work_mem to '128MB', + work_mem to '12MB' + + CAST type tinyint when (= 1 precision) to boolean drop typemod using tinyint-to-boolean, + type datetime to timestamptz drop default drop not null, + type timestamp to timestamptz drop default drop not null, + type json to json + + BEFORE LOAD DO + $$ CREATE SCHEMA IF NOT EXISTS public; $$ +; diff --git a/database/cutover/verify.sh b/database/cutover/verify.sh new file mode 100644 index 00000000000..9966f5fe513 --- /dev/null +++ b/database/cutover/verify.sh @@ -0,0 +1,147 @@ +#!/usr/bin/env bash +# +# Cross-engine migration harness: proves the MySQL 8.0 -> Postgres 17 conversion +# step of the v5 cutover is lossless, on the real application schema. +# +# What it does (all self-contained, nothing touches your dev database): +# 1. Boots a throwaway MySQL 8.0 container on ddev's docker network. +# 2. Runs the full migration suite + a representative seed into it. +# 3. Renders the pgloader recipe (database/cutover/v4-to-v5.load) and runs +# it, copying MySQL -> a scratch Postgres database. +# 4. Verifies NO DATA LOSS: exact COUNT(*) per table on both sides, plus +# per-row content checks of the type-risky columns (bool, bigint, json). +# 5. Tears the throwaway resources down. +# +# Requires: docker, a running ddev project (for `ddev exec artisan` + the +# Postgres container). Run from the repo root: bash database/cutover/verify.sh +# +set -euo pipefail + +# --- config (defaults match a standard ddev "convoy" project) --------------- +PROJECT="${DDEV_PROJECT:-convoy}" +NETWORK="${DDEV_NETWORK:-ddev-${PROJECT}_default}" +PG_CONTAINER="${PG_CONTAINER:-ddev-${PROJECT}-db}" +PG_USER="${PG_USER:-db}" +PG_PASS="${PG_PASS:-db}" + +MYSQL_CONTAINER="pgloader-src-mysql" +MYSQL_DB="convoy_v4" +MYSQL_USER="root" +MYSQL_PASS="root" +PG_TARGET="pgloader_target" + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +LOAD_TEMPLATE="$REPO_ROOT/database/cutover/v4-to-v5.load" +RENDERED="$(mktemp -t pgloader.load.XXXXXX)" + +# pgloader image. The official `dimitri/pgloader` is published amd64-only, and +# pgloader is an SBCL (Lisp) binary, so it only runs where amd64 can be executed: +# natively on x86_64 hosts, or under a *complete* emulator like macOS Docker +# Desktop's Rosetta 2. Under Linux qemu-user emulation (e.g. an arm64 CI/sandbox +# host) SBCL segfaults, so the official image is unusable there. Override with +# PGLOADER_IMAGE= to point at a native-arch pgloader for such hosts. +# NOTE: Debian's packaged pgloader (3.6.7~devel) predates MySQL 8.0's collation +# IDs and dies with "N fell through ECASE expression" on an 8.0 source DB — so a +# self-built Debian image is NOT a drop-in substitute; use a current pgloader. +PGLOADER_IMAGE="${PGLOADER_IMAGE:-dimitri/pgloader:latest}" + +MYSQL_ENV="DB_CONNECTION=mysql DB_HOST=$MYSQL_CONTAINER DB_PORT=3306 DB_DATABASE=$MYSQL_DB DB_USERNAME=$MYSQL_USER DB_PASSWORD=$MYSQL_PASS" + +pg() { docker exec "$PG_CONTAINER" env PGPASSWORD="$PG_PASS" psql -U "$PG_USER" "$@"; } +mysqlc(){ docker exec "$MYSQL_CONTAINER" mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -D "$MYSQL_DB" -N "$@" 2>/dev/null; } + +cleanup() { + echo "--- cleanup ---" + docker rm -f "$MYSQL_CONTAINER" >/dev/null 2>&1 || true + pg -d postgres -c "DROP DATABASE IF EXISTS $PG_TARGET WITH (FORCE);" >/dev/null 2>&1 || true + rm -f "$RENDERED" +} +trap cleanup EXIT + +echo "=== 1. boot throwaway MySQL 8.0 ===" +docker rm -f "$MYSQL_CONTAINER" >/dev/null 2>&1 || true +docker run -d --name "$MYSQL_CONTAINER" --network "$NETWORK" \ + -e MYSQL_ROOT_PASSWORD="$MYSQL_PASS" -e MYSQL_DATABASE="$MYSQL_DB" \ + mysql:8.0 --default-authentication-plugin=mysql_native_password >/dev/null +# `mysqladmin ping` answers OK during MySQL 8's two-phase startup, before the +# server actually accepts DDL — so gate on a real query against the target DB. +ready=0 +for i in $(seq 1 120); do + if docker exec "$MYSQL_CONTAINER" mysql -u"$MYSQL_USER" -p"$MYSQL_PASS" -D "$MYSQL_DB" -e "SELECT 1;" >/dev/null 2>&1; then + ready=1; break + fi + sleep 1 +done +[ "$ready" = "1" ] || { echo "MySQL did not become ready in time." >&2; exit 1; } +echo "MySQL ready." + +echo "=== 2. migrate + seed the real schema into MySQL ===" +ddev exec "$MYSQL_ENV php artisan config:clear" >/dev/null +ddev exec "$MYSQL_ENV php artisan migrate:fresh --seed --seeder=PgloaderHarnessSeeder --force" >/dev/null +echo "Seeded." + +echo "=== 3. render recipe + run pgloader (MySQL -> Postgres) ===" +pg -d postgres -c "DROP DATABASE IF EXISTS $PG_TARGET WITH (FORCE);" >/dev/null +pg -d postgres -c "CREATE DATABASE $PG_TARGET OWNER $PG_USER;" >/dev/null +sed -e "s|\${MYSQL_URL}|mysql://$MYSQL_USER:$MYSQL_PASS@$MYSQL_CONTAINER/$MYSQL_DB|" \ + -e "s|\${PG_URL}|postgresql://$PG_USER:$PG_PASS@db/$PG_TARGET|" \ + "$LOAD_TEMPLATE" > "$RENDERED" +echo "using pgloader image: $PGLOADER_IMAGE" +PGLOADER_LOG="$(mktemp -t pgloader.run.XXXXXX)" +if ! docker run --rm --network "$NETWORK" -v "$RENDERED:/load/rendered.load:ro" \ + "$PGLOADER_IMAGE" pgloader /load/rendered.load >"$PGLOADER_LOG" 2>&1; then + tail -5 "$PGLOADER_LOG" + echo "" + if grep -qiE "exec format error|CORRUPTION WARNING in SBCL|Memory fault|maximum interrupt nesting|ldb>" "$PGLOADER_LOG"; then + echo "pgloader could not execute: '$PGLOADER_IMAGE' is amd64-only and this" >&2 + echo "Docker host cannot run amd64 (no Rosetta-grade emulation). Run this on" >&2 + echo "an x86_64 host / macOS Docker Desktop, or set PGLOADER_IMAGE to a" >&2 + echo "native-arch pgloader (>= 3.6.9 for MySQL 8.0 collation support)." >&2 + elif grep -qiE "fell through ECASE" "$PGLOADER_LOG"; then + echo "This pgloader is too old for a MySQL 8.0 source (unknown collation ID)." >&2 + echo "Set PGLOADER_IMAGE to a pgloader >= 3.6.9." >&2 + fi + rm -f "$PGLOADER_LOG"; exit 1 +fi +tail -3 "$PGLOADER_LOG"; rm -f "$PGLOADER_LOG" + +echo "" +echo "=== 4. verify no data loss ===" +FAIL=0 +printf "%-42s %8s %8s %s\n" "table" "mysql" "pg" "status" +for t in $(mysqlc -e "SHOW TABLES;"); do + m=$(mysqlc -e "SELECT COUNT(*) FROM \`$t\`;" | tr -d '[:space:]') + p=$(pg -d "$PG_TARGET" -t -A -c "SELECT COUNT(*) FROM \"$t\";" 2>/dev/null | tr -d '[:space:]') + { [ "$m" = "0" ] && [ "$p" = "0" ]; } && continue + st="OK"; if [ "$m" != "$p" ]; then st="*** MISMATCH ***"; FAIL=1; fi + printf "%-42s %8s %8s %s\n" "$t" "$m" "$p" "$st" +done + +# Per-row content checks of the conversion-risky column types. +check_identical() { + local label="$1" mysql_sql="$2" pg_sql="$3" + if diff <(mysqlc -e "$mysql_sql") \ + <(pg -d "$PG_TARGET" -t -A -F$'\t' -c "$pg_sql" 2>/dev/null) >/dev/null; then + echo "content OK $label" + else + echo "content FAIL $label"; FAIL=1 + fi +} +echo "" +check_identical "nodes.verify_tls (bool)" \ + "SELECT id,verify_tls FROM nodes ORDER BY id;" \ + "SELECT id, CASE WHEN verify_tls THEN 1 ELSE 0 END FROM nodes ORDER BY id;" +check_identical "nodes.memory (bigint)" \ + "SELECT id,memory FROM nodes ORDER BY id;" \ + "SELECT id, memory FROM nodes ORDER BY id;" +check_identical "activity_logs.properties (json)" \ + "SELECT id,JSON_UNQUOTE(JSON_EXTRACT(properties,'\$.nested.label')) FROM activity_logs ORDER BY id;" \ + "SELECT id, properties->'nested'->>'label' FROM activity_logs ORDER BY id;" + +echo "" +if [ "$FAIL" = "0" ]; then + echo "RESULT: PASS — the MySQL -> Postgres conversion preserved every row and value." +else + echo "RESULT: FAIL — see mismatches above." +fi +exit "$FAIL" diff --git a/database/factories/AddressBlockFactory.php b/database/factories/AddressBlockFactory.php new file mode 100644 index 00000000000..dab8a2f6152 --- /dev/null +++ b/database/factories/AddressBlockFactory.php @@ -0,0 +1,41 @@ + + */ +class AddressBlockFactory extends Factory +{ + /** + * @return array + */ + public function definition(): array + { + return [ + 'address_block_group_id' => AddressBlockGroup::factory(), + 'name' => $this->faker->word(), + 'description' => null, + 'base_ip' => $this->faker->ipv4(), + 'gateway' => $this->faker->ipv4(), + 'mac_address' => null, + 'prefix_length_from' => 24, + 'prefix_length_to' => 32, + ]; + } + + /** The version follows base_ip — it is derived, not stored. */ + public function ipv6(): self + { + return $this->state(fn () => [ + 'base_ip' => $this->faker->ipv6(), + 'gateway' => $this->faker->ipv6(), + 'prefix_length_from' => 48, + 'prefix_length_to' => 128, + ]); + } +} diff --git a/database/factories/AddressBlockGroupFactory.php b/database/factories/AddressBlockGroupFactory.php new file mode 100644 index 00000000000..cbd4fe0733f --- /dev/null +++ b/database/factories/AddressBlockGroupFactory.php @@ -0,0 +1,16 @@ + $this->faker->name(), + 'description' => rand(0, 3) === 3 ? $this->faker->sentence() : null, + ]; + } +} diff --git a/database/factories/AddressFactory.php b/database/factories/AddressFactory.php index 8890afd2191..f4b27a3b57a 100644 --- a/database/factories/AddressFactory.php +++ b/database/factories/AddressFactory.php @@ -2,7 +2,10 @@ namespace Database\Factories; -use Convoy\Models\Address; +use App\Enums\Network\AddressState; +use App\Enums\Network\AddressStateReason; +use App\Models\Address; +use App\Models\AddressBlock; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -17,14 +20,48 @@ class AddressFactory extends Factory */ public function definition(): array { - $type = $this->faker->randomElement(['ipv4', 'ipv6']); - return [ - 'type' => $type, - 'address' => $type === 'ipv4' ? $this->faker->ipv4 : $this->faker->ipv6, - 'cidr' => $this->faker->numberBetween(0, 128), - 'gateway' => $type === 'ipv4' ? $this->faker->ipv4 : $this->faker->ipv6, - 'mac_address' => $this->faker->randomElement([null, $this->faker->macAddress]), + 'address_block_id' => AddressBlock::factory(), + 'server_id' => null, + 'ip' => $this->faker->unique()->ipv4(), + 'prefix_length' => 32, + 'state' => AddressState::Available, ]; } + + /** + * Keep state consistent with server_id: an address created with a server attached is 'assigned' + * unless a state was set explicitly. A reserved address defaults to an operator hold, since + * system reservations are only ever created by the generator/allocator. + */ + public function configure(): static + { + return $this->afterMaking(function (Address $address) { + if ($address->server_id !== null && $address->state === AddressState::Available) { + $address->state = AddressState::Assigned; + } + + if ($address->state === AddressState::Reserved && $address->state_reason === null) { + $address->state_reason = AddressStateReason::Admin; + } + }); + } + + /** A structural address the panel reserved itself (network, broadcast, gateway). */ + public function systemReserved(): self + { + return $this->state(fn () => [ + 'state' => AddressState::Reserved, + 'state_reason' => AddressStateReason::System, + ]); + } + + public function ipv6(): self + { + return $this->state(fn () => [ + 'address_block_id' => AddressBlock::factory()->ipv6(), + 'ip' => $this->faker->unique()->ipv6(), + 'prefix_length' => 128, + ]); + } } diff --git a/database/factories/AddressPoolFactory.php b/database/factories/AddressPoolFactory.php deleted file mode 100644 index 372510b0883..00000000000 --- a/database/factories/AddressPoolFactory.php +++ /dev/null @@ -1,21 +0,0 @@ - $this->faker->name(), - 'created_at' => Carbon::now(), - 'updated_at' => Carbon::now(), - ]; - } -} diff --git a/database/factories/AnchorEnrollmentFactory.php b/database/factories/AnchorEnrollmentFactory.php new file mode 100644 index 00000000000..9d4d0111a15 --- /dev/null +++ b/database/factories/AnchorEnrollmentFactory.php @@ -0,0 +1,44 @@ + */ +class AnchorEnrollmentFactory extends Factory +{ + public function definition(): array + { + return [ + 'uuid' => (string) Str::uuid(), + 'name' => 'pve-new.example.com', + 'mode' => AnchorMode::AGENT, + 'secret' => Str::random(64), + 'enrolled_at' => now(), + 'last_seen_at' => now(), + 'version' => '0.1.0-alpha.1', + 'protocol_min' => AnchorProtocol::VERSION, + 'protocol_max' => AnchorProtocol::VERSION, + 'capabilities' => ['console.qemu.vnc', 'console.qemu.terminal'], + 'reported_facts' => [ + 'hostname' => 'pve-new.example.com', + 'pve_node_name' => 'pve-new', + 'cpu' => ['sockets' => 2, 'cores' => 32, 'threads' => 64], + 'memory_bytes' => 549755813888, + 'observed_source_ip' => '10.0.0.11', + ], + ]; + } + + public function relay(): static + { + return $this->state(fn () => [ + 'mode' => AnchorMode::RELAY, + 'capabilities' => ['console.relay'], + ]); + } +} diff --git a/database/factories/AnchorEnrollmentKeyFactory.php b/database/factories/AnchorEnrollmentKeyFactory.php new file mode 100644 index 00000000000..cc2782f5998 --- /dev/null +++ b/database/factories/AnchorEnrollmentKeyFactory.php @@ -0,0 +1,55 @@ + */ +class AnchorEnrollmentKeyFactory extends Factory +{ + /** + * The plaintext of the last key this factory built, so a test can present + * the token it just created without reaching for the hash. + */ + public static ?string $lastToken = null; + + public function definition(): array + { + $token = AnchorEnrollmentKeyService::TOKEN_PREFIX.Str::random(64); + self::$lastToken = $token; + + return [ + 'uuid' => (string) Str::uuid(), + 'name' => $this->faker->words(2, true), + 'token_hash' => hash('sha256', $token), + 'mode' => null, + 'max_uses' => 1, + 'uses' => 0, + 'expires_at' => now()->addMinutes(AnchorEnrollmentKeyService::DEFAULT_TTL_MINUTES), + ]; + } + + public function revoked(): static + { + return $this->state(fn () => ['revoked_at' => now()]); + } + + public function expired(): static + { + return $this->state(fn () => ['expires_at' => now()->subMinute()]); + } + + public function exhausted(): static + { + return $this->state(fn () => ['max_uses' => 1, 'uses' => 1]); + } + + /** A key with no expiry and no use limit -- the machine-image shape. */ + public function unlimited(): static + { + return $this->state(fn () => ['expires_at' => null, 'max_uses' => null]); + } +} diff --git a/database/factories/BackupFactory.php b/database/factories/BackupFactory.php index 573f2740ddb..b398ffdfe1b 100644 --- a/database/factories/BackupFactory.php +++ b/database/factories/BackupFactory.php @@ -2,8 +2,9 @@ namespace Database\Factories; -use Convoy\Models\Backup; -use Convoy\Models\Server; +use App\Models\Backup; +use App\Models\Server; +use App\Models\Storage; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -11,13 +12,6 @@ */ class BackupFactory extends Factory { - /** - * The name of the factory's corresponding model. - * - * @var string - */ - protected $model = Backup::class; - /** * Define the model's default state. * @@ -26,8 +20,9 @@ class BackupFactory extends Factory public function definition(): array { return [ + 'server_id' => Server::factory(), + 'storage_id' => Storage::factory(), 'uuid' => $this->faker->uuid(), - 'is_successful' => $this->faker->boolean(), 'is_locked' => $this->faker->boolean(), 'name' => $this->faker->word(), 'file_name' => $this->faker->word(), diff --git a/database/factories/ClusterFactory.php b/database/factories/ClusterFactory.php new file mode 100644 index 00000000000..9bf98f40948 --- /dev/null +++ b/database/factories/ClusterFactory.php @@ -0,0 +1,27 @@ + Str::upper(implode(':', str_split(bin2hex(random_bytes(16)), 2))), + 'name' => $this->faker->word(), + 'member_names' => null, + ]; + } + + public function standalone(): static + { + return $this->state([ + 'fingerprint' => null, + 'name' => null, + ]); + } +} diff --git a/database/factories/ISOFactory.php b/database/factories/ISOFactory.php index ba86105951a..25262d807e6 100644 --- a/database/factories/ISOFactory.php +++ b/database/factories/ISOFactory.php @@ -2,7 +2,7 @@ namespace Database\Factories; -use Convoy\Models\ISO; +use App\Models\ISO; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -10,8 +10,6 @@ */ class ISOFactory extends Factory { - protected $model = ISO::class; - /** * Define the model's default state. * @@ -21,12 +19,22 @@ public function definition(): array { return [ 'uuid' => $this->faker->uuid(), - 'is_successful' => $this->faker->boolean(), 'name' => $this->faker->name(), - 'file_name' => "{$this->faker->name()}.iso", + 'file_name' => "{$this->faker->unique()->word()}.iso", + 'url' => 'https://example.invalid/'.$this->faker->unique()->word().'.iso', + 'path' => null, + 'sha256' => hash('sha256', $this->faker->unique()->word()), 'size' => $this->faker->randomNumber(), - 'hidden' => $this->faker->boolean(), - 'completed_at' => $this->faker->dateTime(), + 'hidden' => false, ]; } + + /** An ISO the panel is hosting rather than one the operator links to. */ + public function hosted(): static + { + return $this->state(fn () => [ + 'url' => null, + 'path' => 'iso-'.hash('sha256', $this->faker->unique()->word()).'.iso', + ]); + } } diff --git a/database/factories/LocationFactory.php b/database/factories/LocationFactory.php index d574ccc3a56..f96d82030ca 100644 --- a/database/factories/LocationFactory.php +++ b/database/factories/LocationFactory.php @@ -2,7 +2,7 @@ namespace Database\Factories; -use Convoy\Models\Location; +use App\Models\Location; use Illuminate\Database\Eloquent\Factories\Factory; /** @@ -10,12 +10,7 @@ */ class LocationFactory extends Factory { - /** - * The name of the factory's corresponding model. - * - * @var string - */ - protected $model = Location::class; + private static int $shortCodeSequence = 0; /** * Define the model's default state. @@ -25,7 +20,7 @@ class LocationFactory extends Factory public function definition(): array { return [ - 'short_code' => $this->faker->word(), + 'short_code' => sprintf('loc-%06d', ++self::$shortCodeSequence), 'description' => $this->faker->sentence(), ]; } diff --git a/database/factories/NetworkInterfaceFactory.php b/database/factories/NetworkInterfaceFactory.php new file mode 100644 index 00000000000..efca1fe5c4f --- /dev/null +++ b/database/factories/NetworkInterfaceFactory.php @@ -0,0 +1,35 @@ + Node::factory(), + 'name' => 'vmbr'.$this->faker->unique()->numberBetween(0, 4094), + 'description' => null, + 'is_vlan_aware' => false, + 'vlan_tag' => null, + ]; + } + + /** + * A trunk. Pass a tag to give it a default that untagged servers inherit; + * without one it is a pure trunk where every server carries its own. + */ + public function trunk(?int $vlanTag = null): static + { + return $this->state([ + 'is_vlan_aware' => true, + 'vlan_tag' => $vlanTag, + ]); + } +} diff --git a/database/factories/NodeFactory.php b/database/factories/NodeFactory.php index b6496367090..7aa18d23f2b 100644 --- a/database/factories/NodeFactory.php +++ b/database/factories/NodeFactory.php @@ -2,32 +2,48 @@ namespace Database\Factories; -use Convoy\Models\Node; +use App\Models\Location; +use App\Support\Anchor\AnchorProtocol; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Str; class NodeFactory extends Factory { - protected $model = Node::class; - public function definition(): array { return [ + 'location_id' => Location::factory(), + 'display_name' => $this->faker->words(2, true), 'name' => $this->faker->word(), - 'cluster' => 'proxmox', 'verify_tls' => true, - 'fqdn' => $this->faker->word(), + 'fqdn' => $this->faker->domainName(), 'token_id' => $this->faker->word(), - 'secret' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'token_secret' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 'port' => 8006, + 'socket_count' => 2, + 'core_count' => 16, + 'cpu_count' => 32, 'memory' => 68719476736, // 64 gb 'memory_overallocate' => 0, - 'disk' => 137438953472, // 128 gb - 'disk_overallocate' => 0, - 'vm_storage' => 'local', - 'backup_storage' => 'local', - 'iso_storage' => 'local', - 'network' => 'vmbr0', - 'coterm_id' => null, + // No agent by default: that is the v4 shape, and the one a test + // has to opt out of rather than into. + 'agent_uuid' => null, ]; } + + /** A node whose host is running an enrolled, healthy agent. */ + public function withAgent(): static + { + return $this->state(fn () => [ + 'agent_uuid' => (string) Str::uuid(), + 'agent_secret' => Str::random(64), + 'agent_public_url' => 'https://'.$this->faker->domainName(), + 'agent_enrolled_at' => now(), + 'agent_last_seen_at' => now(), + 'agent_version' => '0.1.0-alpha.1', + 'agent_protocol_min' => AnchorProtocol::VERSION, + 'agent_protocol_max' => AnchorProtocol::VERSION, + 'agent_capabilities' => ['console.qemu.vnc', 'console.qemu.terminal'], + ]); + } } diff --git a/database/factories/RelayFactory.php b/database/factories/RelayFactory.php new file mode 100644 index 00000000000..12c4f1db778 --- /dev/null +++ b/database/factories/RelayFactory.php @@ -0,0 +1,34 @@ + */ +class RelayFactory extends Factory +{ + public function definition(): array + { + return [ + 'uuid' => (string) Str::uuid(), + 'name' => $this->faker->words(2, true), + 'public_url' => 'https://'.$this->faker->domainName(), + 'secret' => Str::random(64), + ]; + } + + public function enrolled(): static + { + return $this->state(fn () => [ + 'enrolled_at' => now(), + 'last_seen_at' => now(), + 'version' => '0.1.0-alpha.1', + 'protocol_min' => AnchorProtocol::VERSION, + 'protocol_max' => AnchorProtocol::VERSION, + 'capabilities' => ['console.relay'], + ]); + } +} diff --git a/database/factories/ServerDiskFactory.php b/database/factories/ServerDiskFactory.php new file mode 100644 index 00000000000..64061dcebe5 --- /dev/null +++ b/database/factories/ServerDiskFactory.php @@ -0,0 +1,28 @@ + Server::factory(), + 'storage_id' => Storage::factory(), + // Bytes in; StorageSizeCast stores MiB (matches ServerFactory.disk). + 'size' => 20 * 1024 * 1024 * 1024, + 'interface' => null, + 'is_primary' => true, + 'disk_index' => 0, + ]; + } + + public function secondary(): static + { + return $this->state(fn () => ['is_primary' => false, 'disk_index' => 1]); + } +} diff --git a/database/factories/ServerFactory.php b/database/factories/ServerFactory.php index f858c18d35a..483216965c7 100644 --- a/database/factories/ServerFactory.php +++ b/database/factories/ServerFactory.php @@ -2,20 +2,15 @@ namespace Database\Factories; -use Convoy\Models\Server; -use Convoy\Services\Servers\ServerCreationService; +use App\Models\Node; +use App\Models\Storage; +use App\Models\User; +use App\Services\Servers\ServerCreationService; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Facades\App; class ServerFactory extends Factory { - /** - * The name of the factory's corresponding model. - * - * @var string - */ - protected $model = Server::class; - /** * Define the model's default state. */ @@ -24,6 +19,9 @@ public function definition(): array $uuid = App::make(ServerCreationService::class)->generateUniqueUuidCombo(); return [ + 'user_id' => User::factory(), + 'node_id' => Node::factory(), + 'storage_id' => Storage::factory(), 'uuid' => $uuid, 'uuid_short' => substr($uuid, 0, 8), 'hostname' => $this->faker->domainName(), @@ -32,8 +30,8 @@ public function definition(): array 'cpu' => 2, 'memory' => 2048 * 1024 * 1024, 'disk' => 20 * 1024 * 1024 * 1024, - 'backup_limit' => 16, - 'snapshot_limit' => 16, + 'backup_count_limit' => 16, + 'backup_size_limit' => 100 * 1024 * 1024 * 1024, 'bandwidth_limit' => 100 * 1024 * 1024 * 1024, ]; } diff --git a/database/factories/ServerPresetFactory.php b/database/factories/ServerPresetFactory.php new file mode 100644 index 00000000000..100fa22c2ad --- /dev/null +++ b/database/factories/ServerPresetFactory.php @@ -0,0 +1,38 @@ + + */ +class ServerPresetFactory extends Factory +{ + private static int $nameSequence = 0; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => sprintf('Preset %06d', ++self::$nameSequence), + 'description' => $this->faker->sentence(), + // Node-scoped settings are left out on purpose: the default preset + // has to be creatable without a node existing first. + 'settings' => [ + 'cpu' => 2, + 'memory' => 2048, + 'disk' => 20480, + 'backup_count' => 2, + 'backup_size' => 40960, + 'addresses_ipv4_count' => 1, + 'addresses_ipv6_count' => 0, + ], + ]; + } +} diff --git a/database/factories/StorageFactory.php b/database/factories/StorageFactory.php new file mode 100644 index 00000000000..7fb16c09003 --- /dev/null +++ b/database/factories/StorageFactory.php @@ -0,0 +1,23 @@ + rand(0, 3) === 3 ? $this->faker->words(2, true) : null, + 'description' => rand(0, 3) === 3 ? $this->faker->sentence() : null, + 'name' => $this->faker->word(), + 'size' => rand(60, 100) * 1024 * 1024 * 1024, + // What a storage holds is read off PVE's list, so a factory sets + // the list rather than seven flags derived from it. + 'pve_content' => 'images,rootdir,vztmpl,backup,iso,snippets,import', + ]; + } +} diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index fe15bf9b5f2..02a500daf47 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -2,8 +2,9 @@ namespace Database\Factories; -use Convoy\Models\User; +use App\Models\User; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; /** @@ -22,7 +23,7 @@ public function definition(): array 'name' => fake()->name(), 'email' => fake()->safeEmail(), 'email_verified_at' => now(), - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'password' => Hash::make('password'), 'remember_token' => Str::random(10), ]; } diff --git a/database/factories/VlanFactory.php b/database/factories/VlanFactory.php new file mode 100644 index 00000000000..2e37d816c37 --- /dev/null +++ b/database/factories/VlanFactory.php @@ -0,0 +1,22 @@ + NetworkInterface::factory(), + 'tag' => $this->faker->unique()->numberBetween(1, 4094), + 'name' => $this->faker->word(), + 'description' => null, + ]; + } +} diff --git a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php index 5cc9f78b1b6..b490e24f5a0 100644 --- a/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php +++ b/database/migrations/2014_10_12_200000_add_two_factor_columns_to_users_table.php @@ -14,17 +14,17 @@ public function up(): void { Schema::table('users', function (Blueprint $table) { $table->text('two_factor_secret') - ->after('password') - ->nullable(); + ->after('password') + ->nullable(); $table->text('two_factor_recovery_codes') - ->after('two_factor_secret') - ->nullable(); + ->after('two_factor_secret') + ->nullable(); if (Fortify::confirmsTwoFactorAuthentication()) { $table->timestamp('two_factor_confirmed_at') - ->after('two_factor_recovery_codes') - ->nullable(); + ->after('two_factor_recovery_codes') + ->nullable(); } }); } diff --git a/database/migrations/2022_07_14_232223_nodes_table.php b/database/migrations/2022_07_14_232223_nodes_table.php index 68a72752f5e..7b4c1fa3ab4 100644 --- a/database/migrations/2022_07_14_232223_nodes_table.php +++ b/database/migrations/2022_07_14_232223_nodes_table.php @@ -20,7 +20,7 @@ public function up(): void $table->string('password'); $table->integer('port'); $table->string('auth_type'); - //$table->foreignId('group_id')->constrained()->onDelete('cascade'); + // $table->foreignId('group_id')->constrained()->onDelete('cascade'); $table->integer('latency')->nullable(); $table->timestamp('last_pinged')->nullable(); $table->timestamps(); diff --git a/database/migrations/2022_07_27_001056_clear_server_id_on_server_delete_in_ip_tables.php b/database/migrations/2022_07_27_001056_clear_server_id_on_server_delete_in_ip_tables.php index 903090828e2..0073a7fa3bd 100644 --- a/database/migrations/2022_07_27_001056_clear_server_id_on_server_delete_in_ip_tables.php +++ b/database/migrations/2022_07_27_001056_clear_server_id_on_server_delete_in_ip_tables.php @@ -13,7 +13,7 @@ public function up(): void { Schema::table('ip_addresses', function (Blueprint $table) { $table->dropForeign(['server_id']); - //$table->foreignId('server_id')->after('id')->nullable()->change()->constrained()->nullOnDelete(); + // $table->foreignId('server_id')->after('id')->nullable()->change()->constrained()->nullOnDelete(); $table->foreign('server_id') ->references('id') ->on('servers') @@ -26,7 +26,6 @@ public function up(): void */ public function down(): void { - Schema::table('ip_addresses', function (Blueprint $table) { - }); + Schema::table('ip_addresses', function (Blueprint $table) {}); } }; diff --git a/database/migrations/2022_12_06_233100_move_network_column_in_nodes_table.php b/database/migrations/2022_12_06_233100_move_network_column_in_nodes_table.php index c718ccabe66..38b09a27e86 100644 --- a/database/migrations/2022_12_06_233100_move_network_column_in_nodes_table.php +++ b/database/migrations/2022_12_06_233100_move_network_column_in_nodes_table.php @@ -2,7 +2,6 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; return new class extends Migration @@ -13,7 +12,7 @@ public function up(): void { Schema::table('nodes', function (Blueprint $table) { - DB::statement('ALTER TABLE nodes MODIFY COLUMN network varchar(255) AFTER backup_storage'); + $table->string('network')->after('backup_storage')->change(); }); } @@ -23,7 +22,7 @@ public function up(): void public function down(): void { Schema::table('nodes', function (Blueprint $table) { - DB::statement('ALTER TABLE nodes MODIFY COLUMN network varchar(255) AFTER vm_storage'); + $table->string('network')->after('vm_storage')->change(); }); } }; diff --git a/database/migrations/2022_12_14_083707_create_settings_table.php b/database/migrations/2022_12_14_083707_create_settings_table.php new file mode 100644 index 00000000000..dd0be6f6d42 --- /dev/null +++ b/database/migrations/2022_12_14_083707_create_settings_table.php @@ -0,0 +1,24 @@ +id(); + + $table->string('group'); + $table->string('name'); + $table->boolean('locked')->default(false); + $table->json('payload'); + + $table->timestamps(); + + $table->unique(['group', 'name']); + }); + } +}; diff --git a/database/migrations/2022_12_25_011208_fix_node_id_column_order_in_template_groups_table.php b/database/migrations/2022_12_25_011208_fix_node_id_column_order_in_template_groups_table.php index f8a32669c5b..8732c7ddfa9 100644 --- a/database/migrations/2022_12_25_011208_fix_node_id_column_order_in_template_groups_table.php +++ b/database/migrations/2022_12_25_011208_fix_node_id_column_order_in_template_groups_table.php @@ -2,7 +2,6 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; return new class extends Migration @@ -13,7 +12,8 @@ public function up(): void { Schema::table('template_groups', function (Blueprint $table) { - DB::statement('ALTER TABLE template_groups MODIFY COLUMN node_id bigint unsigned AFTER id'); + + $table->unsignedBigInteger('node_id')->after('id')->change(); }); } @@ -23,7 +23,7 @@ public function up(): void public function down(): void { Schema::table('template_groups', function (Blueprint $table) { - DB::statement('ALTER TABLE template_groups MODIFY COLUMN node_id bigint unsigned AFTER updated_at'); + $table->unsignedBigInteger('node_id')->after('updated_at')->change(); }); } }; diff --git a/database/migrations/2023_05_11_005040_add_coterm_to_nodes_table.php b/database/migrations/2023_05_11_005040_add_coterm_to_nodes_table.php index 795376396c2..58a52c4ed79 100644 --- a/database/migrations/2023_05_11_005040_add_coterm_to_nodes_table.php +++ b/database/migrations/2023_05_11_005040_add_coterm_to_nodes_table.php @@ -4,7 +4,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class extends Migration +{ /** * Run the migrations. */ diff --git a/database/migrations/2023_05_11_042804_make_node_secret_encrypted_in_nodes_table.php b/database/migrations/2023_05_11_042804_make_node_secret_encrypted_in_nodes_table.php index aa31246ee66..7c383c099f1 100644 --- a/database/migrations/2023_05_11_042804_make_node_secret_encrypted_in_nodes_table.php +++ b/database/migrations/2023_05_11_042804_make_node_secret_encrypted_in_nodes_table.php @@ -5,7 +5,8 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class extends Migration +{ /** * Run the migrations. */ @@ -14,7 +15,6 @@ public function up(): void Schema::table('nodes', function (Blueprint $table) { $nodes = DB::table('nodes')->get()->toArray(); - foreach ($nodes as $node) { DB::table('nodes') ->where('id', $node->id) @@ -31,7 +31,6 @@ public function down(): void Schema::table('nodes', function (Blueprint $table) { $nodes = DB::table('nodes')->get()->toArray(); - foreach ($nodes as $node) { DB::table('nodes') ->where('id', $node->id) diff --git a/database/migrations/2023_05_21_015205_move_port_column_to_behind_fqdn_in_nodes_table.php b/database/migrations/2023_05_21_015205_move_port_column_to_behind_fqdn_in_nodes_table.php index 1d7df8926c7..a95a0937215 100644 --- a/database/migrations/2023_05_21_015205_move_port_column_to_behind_fqdn_in_nodes_table.php +++ b/database/migrations/2023_05_21_015205_move_port_column_to_behind_fqdn_in_nodes_table.php @@ -2,24 +2,23 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; return new class extends Migration { - /** - * Run the migrations. - */ public function up(): void { - DB::statement('ALTER TABLE nodes MODIFY COLUMN port int AFTER fqdn'); + Schema::table('nodes', function (Blueprint $table) { + // Explicitly include all desired attributes for Laravel 11 + $table->integer('port')->nullable(false)->after('fqdn')->change(); + }); } - /** - * Reverse the migrations. - */ public function down(): void { - DB::statement('ALTER TABLE nodes MODIFY COLUMN port int AFTER secret'); + Schema::table('nodes', function (Blueprint $table) { + // Move the column back with all necessary attributes specified + $table->integer('port')->nullable(false)->after('secret')->change(); + }); } }; diff --git a/database/migrations/2023_05_28_032248_add_uuid_column_to_users_table.php b/database/migrations/2023_05_28_032248_add_uuid_column_to_users_table.php index 24ec3d60df3..13054bfe07a 100644 --- a/database/migrations/2023_05_28_032248_add_uuid_column_to_users_table.php +++ b/database/migrations/2023_05_28_032248_add_uuid_column_to_users_table.php @@ -1,8 +1,8 @@ char('uuid', 36)->nullable()->after('id'); }); - DB::statement('UPDATE users SET uuid=(select UUID())'); + User::chunk(100, function ($users) { + foreach ($users as $user) { + $user->uuid = Str::uuid()->toString(); + $user->save(); + } + }); } /** diff --git a/database/migrations/2023_06_04_153504_create_address_table_that_uses_ip_pools.php b/database/migrations/2023_06_04_153504_create_address_table_that_uses_ip_pools.php index 40ae201d0fe..8239d2181ac 100644 --- a/database/migrations/2023_06_04_153504_create_address_table_that_uses_ip_pools.php +++ b/database/migrations/2023_06_04_153504_create_address_table_that_uses_ip_pools.php @@ -2,11 +2,12 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; -use Illuminate\Support\Collection; use Illuminate\Support\Arr; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Schema; -return new class extends Migration { +return new class extends Migration +{ /** * Run the migrations. */ @@ -33,7 +34,8 @@ public function up(): void /** * The key is the node id and the value is the address pool id - * @var array $pools + * + * @var array $pools */ $pools = []; @@ -53,14 +55,14 @@ public function up(): void $payload = []; foreach ($addresses as $address) { - if (!array_key_exists($address->node_id, $pools)) { + if (! array_key_exists($address->node_id, $pools)) { $poolId = DB::table('address_pools')->insertGetId([ - 'name' => "Node {$address->fqdn}" + 'name' => "Node {$address->fqdn}", ]); DB::table('address_pool_to_node')->insert([ 'address_pool_id' => $poolId, - 'node_id' => $address->node_id + 'node_id' => $address->node_id, ]); $pools[$address->node_id] = $poolId; @@ -134,9 +136,7 @@ public function down(): void $addresses = DB::table('temp_ip_addresses')->where('address_pool_id', '=', $pool->id)->get(); foreach ($addresses as $address) { - foreach ($linkedNodeIds as $linkedNodeId) { - $payload[] = [ 'node_id' => $linkedNodeId, 'server_id' => $address->server_id, @@ -151,7 +151,6 @@ public function down(): void ]; } } - } DB::table('ip_addresses')->insert($payload); diff --git a/database/migrations/2023_09_03_174812_move_types_column_in_ip_addresses_table.php b/database/migrations/2023_09_03_174812_move_types_column_in_ip_addresses_table.php index db9139ba82d..27d3725e7c1 100644 --- a/database/migrations/2023_09_03_174812_move_types_column_in_ip_addresses_table.php +++ b/database/migrations/2023_09_03_174812_move_types_column_in_ip_addresses_table.php @@ -11,7 +11,10 @@ */ public function up(): void { - DB::statement('ALTER TABLE ip_addresses MODIFY COLUMN type varchar(255) AFTER server_id'); + Schema::table('ip_addresses', function (Blueprint $table) { + // Modify the 'type' column to be after 'server_id' with all necessary attributes + $table->string('type', 255)->after('server_id')->change(); + }); } /** @@ -19,6 +22,9 @@ public function up(): void */ public function down(): void { - DB::statement('ALTER TABLE ip_addresses MODIFY COLUMN type varchar(255) AFTER mac_address'); + Schema::table('ip_addresses', function (Blueprint $table) { + // Move the 'type' column to be after 'mac_address' with all necessary attributes + $table->string('type', 255)->after('mac_address')->change(); + }); } }; diff --git a/database/migrations/2023_11_11_175741_create_coterms_table.php b/database/migrations/2023_11_11_175741_create_coterms_table.php index 8a1bafef189..d6a414f2c35 100644 --- a/database/migrations/2023_11_11_175741_create_coterms_table.php +++ b/database/migrations/2023_11_11_175741_create_coterms_table.php @@ -1,10 +1,11 @@ id(); + $table->foreignId('server_id')->constrained()->cascadeOnDelete(); + $table->foreignId('template_id')->nullable()->constrained()->cascadeOnDelete(); + $table->boolean('should_create_vm'); + $table->boolean('start_on_completion'); + $table->boolean('delete_successful'); + $table->timestamp('deleted_vm_at')->nullable(); + $table->boolean('build_successful'); + $table->integer('build_progress'); + $table->timestamp('built_vm_at')->nullable(); + $table->boolean('sync_successful'); + $table->timestamp('synced_vm_at')->nullable(); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('deployments'); + } +}; diff --git a/database/migrations/2024_09_27_005757_create_snapshots_table.php b/database/migrations/2024_09_27_005757_create_snapshots_table.php new file mode 100644 index 00000000000..6ae35125451 --- /dev/null +++ b/database/migrations/2024_09_27_005757_create_snapshots_table.php @@ -0,0 +1,37 @@ +id(); + $table->uuid()->unique(); + $table->foreignId('server_id')->constrained()->cascadeOnDelete(); + $table->foreignId('snapshot_id')->nullable()->constrained('snapshots')->cascadeOnDelete( + ); + $table->string('name'); + $table->string('description')->nullable(); + $table->boolean('is_locked')->default(false); + $table->string('errors')->nullable(); + $table->unsignedBigInteger('size')->default(0); + $table->timestamp('completed_at')->nullable(); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('snapshots'); + } +}; diff --git a/database/migrations/2024_10_03_222715_change_backups_completed_at_to_errors_column.php b/database/migrations/2024_10_03_222715_change_backups_completed_at_to_errors_column.php new file mode 100644 index 00000000000..671e82e028a --- /dev/null +++ b/database/migrations/2024_10_03_222715_change_backups_completed_at_to_errors_column.php @@ -0,0 +1,43 @@ +whereNotNull('completed_at') + ->where('is_successful', 0) + ->delete(); + + Schema::table('backups', function (Blueprint $table) { + $table->string('description')->nullable()->after('name'); + $table->string('errors')->nullable()->after('description'); + + $table->dropSoftDeletes(); + $table->dropColumn(['is_successful', 'updated_at']); + + // Explicitly define 'is_locked' attributes to prevent unintended behavior + $table->boolean('is_locked')->default(false)->nullable(false)->after('description')->change(); + }); + } + + public function down(): void + { + Schema::table('backups', function (Blueprint $table) { + $table->dropColumn(['description', 'errors']); + + // Re-apply all attributes to 'is_locked' in down migration + $table->boolean('is_locked')->nullable()->default(null)->after('is_successful')->change(); + + $table->boolean('is_successful')->default(false)->after('server_id'); + $table->timestamp('updated_at')->nullable()->after('created_at'); + $table->softDeletes()->after('updated_at'); + }); + } +}; diff --git a/database/migrations/2024_10_10_011714_create_storages_table.php b/database/migrations/2024_10_10_011714_create_storages_table.php new file mode 100644 index 00000000000..56d98514f8b --- /dev/null +++ b/database/migrations/2024_10_10_011714_create_storages_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('nickname')->nullable(); + $table->string('description')->nullable(); + $table->string('name'); + $table->unsignedInteger('size'); + $table->boolean('is_shareable')->default(false); + $table->boolean('has_kvm'); + $table->boolean('has_lxc'); + $table->boolean('has_lxc_templates'); + $table->boolean('has_backups'); + $table->boolean('has_iso'); + $table->boolean('has_snippets'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('storages'); + } +}; diff --git a/database/migrations/2024_10_10_023833_create_storage_to_nodes_table.php b/database/migrations/2024_10_10_023833_create_storage_to_nodes_table.php new file mode 100644 index 00000000000..22e88bc9ea3 --- /dev/null +++ b/database/migrations/2024_10_10_023833_create_storage_to_nodes_table.php @@ -0,0 +1,27 @@ +foreignId('storage_id')->constrained()->onDelete('cascade'); + $table->foreignId('node_id')->constrained()->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('storage_to_node'); + } +}; diff --git a/database/migrations/2024_10_10_025946_remove_timestamps_from_address_pools_table.php b/database/migrations/2024_10_10_025946_remove_timestamps_from_address_pools_table.php new file mode 100644 index 00000000000..ce95c363ac8 --- /dev/null +++ b/database/migrations/2024_10_10_025946_remove_timestamps_from_address_pools_table.php @@ -0,0 +1,30 @@ +dropColumn('created_at', 'updated_at'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('address_pools', function (Blueprint $table) { + $table->after('name', fn (Blueprint $table) => $table->timestamps()); + }); + + DB::table('address_pools')->update(['created_at' => now()]); + } +}; diff --git a/database/migrations/2024_10_10_030421_remove_storage_columns_from_nodes_table.php b/database/migrations/2024_10_10_030421_remove_storage_columns_from_nodes_table.php new file mode 100644 index 00000000000..b64328dda47 --- /dev/null +++ b/database/migrations/2024_10_10_030421_remove_storage_columns_from_nodes_table.php @@ -0,0 +1,310 @@ +foreignId('storage_id')->after('server_id')->nullable()->constrained()->cascadeOnDelete(); + }); + + Schema::table('iso_library', function (Blueprint $table) { + $table->foreignId('storage_id')->after('uuid')->nullable()->constrained()->onDelete('cascade'); + $table->dropColumn('updated_at'); + }); + + Schema::table('servers', function (Blueprint $table) { + $table->foreignId('storage_id')->after('node_id')->nullable()->constrained()->onDelete('cascade'); + $table->dropColumn('updated_at'); + }); + + // First, create storage entries using the existing node information + DB::transaction(function () { + $nodes = DB::table('nodes')->get(); + $storageIdsByNode = []; + $vmStorageIdsByNode = []; + $isoStorageIdsByNode = []; + + foreach ($nodes as $node) { + // Create a map to track unique storage paths and their IDs + $storagePathMap = []; + + // Process VM storage + $vmPath = $node->vm_storage; + if (! isset($storagePathMap[$vmPath])) { + $vmStorageId = DB::table('storages')->insertGetId([ + 'nickname' => 'VM Storage', + 'description' => 'Migrated from node settings', + 'name' => $vmPath, + 'size' => $node->disk, + 'is_shareable' => false, + 'has_kvm' => true, + 'has_lxc' => false, + 'has_lxc_templates' => false, + 'has_backups' => false, + 'has_iso' => false, + 'has_snippets' => false, + ]); + + $storagePathMap[$vmPath] = [ + 'id' => $vmStorageId, + 'has_kvm' => true, + 'has_backups' => false, + 'has_iso' => false, + ]; + + // Store VM storage ID for this node to use with servers later + $vmStorageIdsByNode[$node->id] = $vmStorageId; + } else { + // Update the existing storage to add VM capability + DB::table('storages') + ->where('id', $storagePathMap[$vmPath]['id']) + ->update(['has_kvm' => true]); + $storagePathMap[$vmPath]['has_kvm'] = true; + + // Store VM storage ID for this node to use with servers later + $vmStorageIdsByNode[$node->id] = $storagePathMap[$vmPath]['id']; + } + + // Process Backup storage + $backupPath = $node->backup_storage; + if (! isset($storagePathMap[$backupPath])) { + $backupStorageId = DB::table('storages')->insertGetId([ + 'nickname' => 'Backup Storage', + 'description' => 'Migrated from node settings', + 'name' => $backupPath, + 'size' => $node->disk, + 'is_shareable' => false, + 'has_kvm' => false, + 'has_lxc' => false, + 'has_lxc_templates' => false, + 'has_backups' => true, + 'has_iso' => false, + 'has_snippets' => false, + ]); + + $storagePathMap[$backupPath] = [ + 'id' => $backupStorageId, + 'has_kvm' => false, + 'has_backups' => true, + 'has_iso' => false, + ]; + + // Store backup storage ID for this node to use with backups later + $storageIdsByNode[$node->id] = $backupStorageId; + } else { + // Update the existing storage to add Backup capability + DB::table('storages') + ->where('id', $storagePathMap[$backupPath]['id']) + ->update(['has_backups' => true]); + $storagePathMap[$backupPath]['has_backups'] = true; + + // Store backup storage ID for this node to use with backups later + $storageIdsByNode[$node->id] = $storagePathMap[$backupPath]['id']; + } + + // Process ISO storage + $isoPath = $node->iso_storage; + if (! isset($storagePathMap[$isoPath])) { + $isoStorageId = DB::table('storages')->insertGetId([ + 'nickname' => 'ISO Storage', + 'description' => 'Migrated from node settings', + 'name' => $isoPath, + 'size' => $node->disk, + 'is_shareable' => false, + 'has_kvm' => false, + 'has_lxc' => false, + 'has_lxc_templates' => false, + 'has_backups' => false, + 'has_iso' => true, + 'has_snippets' => false, + ]); + + $storagePathMap[$isoPath] = [ + 'id' => $isoStorageId, + 'has_kvm' => false, + 'has_backups' => false, + 'has_iso' => true, + ]; + + // Store ISO storage ID for this node to use with ISO library later + $isoStorageIdsByNode[$node->id] = $isoStorageId; + } else { + // Update the existing storage to add ISO capability + DB::table('storages') + ->where('id', $storagePathMap[$isoPath]['id']) + ->update(['has_iso' => true]); + $storagePathMap[$isoPath]['has_iso'] = true; + + // Store ISO storage ID for this node to use with ISO library later + $isoStorageIdsByNode[$node->id] = $storagePathMap[$isoPath]['id']; + } + + // Update nicknames based on combined capabilities + foreach ($storagePathMap as $path => $storage) { + $capabilities = []; + if ($storage['has_kvm']) { + $capabilities[] = 'VM'; + } + if ($storage['has_backups']) { + $capabilities[] = 'Backup'; + } + if ($storage['has_iso']) { + $capabilities[] = 'ISO'; + } + + $nickname = implode('/', $capabilities).' Storage'; + + DB::table('storages') + ->where('id', $storage['id']) + ->update(['nickname' => $nickname]); + + // Link storage to the node + DB::table('storage_to_node')->insert([ + 'storage_id' => $storage['id'], + 'node_id' => $node->id, + ]); + } + } + + // Now update all backups to use the appropriate storage_id + $servers = DB::table('servers')->get(); + foreach ($servers as $server) { + if (isset($storageIdsByNode[$server->node_id])) { + DB::table('backups') + ->where('server_id', $server->id) + ->update(['storage_id' => $storageIdsByNode[$server->node_id]]); + } + + // Update the server's storage_id to use the VM storage + if (isset($vmStorageIdsByNode[$server->node_id])) { + DB::table('servers') + ->where('id', $server->id) + ->update(['storage_id' => $vmStorageIdsByNode[$server->node_id]]); + } + } + + // Update ISO library items to use the appropriate ISO storage + // ISO library doesn't have server_id, it directly has node_id + $isoLibraryItems = DB::table('iso_library') + ->whereNotNull('node_id') + ->get(); + + foreach ($isoLibraryItems as $iso) { + if (isset($isoStorageIdsByNode[$iso->node_id])) { + DB::table('iso_library') + ->where('id', $iso->id) + ->update(['storage_id' => $isoStorageIdsByNode[$iso->node_id]]); + } + } + }); + + // Now drop the columns that are no longer needed + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn([ + 'disk', + 'disk_overallocate', + 'vm_storage', + 'backup_storage', + 'iso_storage', + ]); + }); + + Schema::table('backups', function (Blueprint $table) { + $table->unsignedBigInteger('storage_id')->nullable(false)->change(); + }); + + Schema::table('iso_library', function (Blueprint $table) { + $table->unsignedBigInteger('storage_id')->nullable(false)->change(); + $table->dropForeign(['node_id']); + $table->dropColumn('node_id'); + }); + + Schema::table('servers', function (Blueprint $table) { + $table->unsignedBigInteger('storage_id')->nullable(false)->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('backups', function (Blueprint $table) { + $table->dropConstrainedForeignId('storage_id'); + }); + + // DANGER: This will delete all ISO library entries, which may not be desired. + DB::table('iso_library')->truncate(); + Schema::table('iso_library', function (Blueprint $table) { + $table->dropForeign(['storage_id']); + $table->dropColumn('storage_id'); + $table->foreignId('node_id')->after('uuid')->constrained()->onDelete('cascade'); + $table->timestamp('updated_at')->nullable()->after('created_at'); + }); + + Schema::table('servers', function (Blueprint $table) { + $table->dropForeign(['storage_id']); + $table->dropColumn('storage_id'); + $table->timestamp('updated_at')->nullable()->after('created_at'); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->after('memory_overallocate', function (Blueprint $table) { + $table->integer('disk')->nullable()->unsigned(); + $table->integer('disk_overallocate')->default(0); + $table->string('vm_storage')->nullable(); + $table->string('backup_storage')->nullable(); + $table->string('iso_storage')->nullable(); + }); + }); + + // Restore the original storage path values from the storages table + DB::transaction(function () { + $nodes = DB::table('nodes')->get(); + + foreach ($nodes as $node) { + // Find storages linked to this node + $nodeStorages = DB::table('storage_to_node') + ->where('node_id', $node->id) + ->join('storages', 'storage_to_node.storage_id', '=', 'storages.id') + ->select('storages.*') + ->get(); + + // Find storages by capability + $vmStorage = $nodeStorages->firstWhere('has_kvm', true); + $backupStorage = $nodeStorages->firstWhere('has_backups', true); + $isoStorage = $nodeStorages->firstWhere('has_iso', true); + + // Default size from the first storage + $diskSize = $nodeStorages->first() ? $nodeStorages->first()->size : 0; + + // Update the node with values from the storages + DB::table('nodes') + ->where('id', $node->id) + ->update([ + 'disk' => $diskSize, + 'disk_overallocate' => 0, // Default value + 'vm_storage' => $vmStorage ? $vmStorage->name : 'NOT_DETECTED', + 'backup_storage' => $backupStorage ? $backupStorage->name : 'NOT_DETECTED', + 'iso_storage' => $isoStorage ? $isoStorage->name : 'NOT_DETECTED', + ]); + } + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->integer('disk')->unsigned()->nullable(false)->change(); + $table->string('vm_storage')->nullable(false)->change(); + $table->string('backup_storage')->nullable(false)->change(); + $table->string('iso_storage')->nullable(false)->change(); + }); + } +}; diff --git a/database/migrations/2024_10_10_033133_update_backup_snapshot_limit_columns_on_servers_table.php b/database/migrations/2024_10_10_033133_update_backup_snapshot_limit_columns_on_servers_table.php new file mode 100644 index 00000000000..d84a50fce73 --- /dev/null +++ b/database/migrations/2024_10_10_033133_update_backup_snapshot_limit_columns_on_servers_table.php @@ -0,0 +1,55 @@ +integer('snapshot_limit')->nullable()->change(); + $table->integer('backup_limit')->nullable()->change(); + $table->integer('bandwidth_limit')->nullable()->change(); + $table->unsignedInteger('bandwidth_usage')->default(0)->change(); + }); + + DB::table('servers')->whereNull('snapshot_limit')->update(['snapshot_limit' => -1]); + DB::table('servers')->whereNull('backup_limit')->update(['backup_limit' => -1]); + DB::table('servers')->whereNull('bandwidth_limit')->update(['bandwidth_limit' => -1]); + + Schema::table('servers', function (Blueprint $table) { + $table->renameColumn('snapshot_limit', 'snapshot_count_limit'); + $table->renameColumn('backup_limit', 'backup_count_limit'); + $table->integer('snapshot_size_limit')->after('snapshot_count_limit'); + $table->integer('backup_size_limit')->after('backup_count_limit'); + }); + + Schema::table('servers', function (Blueprint $table) { + $table->integer('snapshot_count_limit')->nullable(false)->change(); + $table->integer('backup_count_limit')->nullable(false)->change(); + $table->integer('bandwidth_limit')->nullable(false)->change(); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->integer('snapshot_count_limit')->nullable()->change(); + $table->integer('backup_count_limit')->nullable()->change(); + $table->integer('bandwidth_limit')->nullable()->change(); + $table->integer('bandwidth_usage')->default(0)->change(); + }); + + DB::table('servers')->where('snapshot_count_limit', -1)->update(['snapshot_count_limit' => null]); + DB::table('servers')->where('backup_count_limit', -1)->update(['backup_count_limit' => null]); + DB::table('servers')->where('bandwidth_limit', -1)->update(['bandwidth_limit' => null]); + + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('snapshot_size_limit', 'backup_size_limit'); + $table->renameColumn('snapshot_count_limit', 'snapshot_limit'); + $table->renameColumn('backup_count_limit', 'backup_limit'); + }); + } +}; diff --git a/database/migrations/2024_10_10_192039_update_size_column_on_backups_snapshots_tables.php b/database/migrations/2024_10_10_192039_update_size_column_on_backups_snapshots_tables.php new file mode 100644 index 00000000000..f93a8cb6617 --- /dev/null +++ b/database/migrations/2024_10_10_192039_update_size_column_on_backups_snapshots_tables.php @@ -0,0 +1,30 @@ +unsignedInteger('size')->nullable(false)->change(); + }); + + Schema::table('snapshots', function (Blueprint $table) { + $table->unsignedInteger('size')->nullable(false)->change(); + }); + } + + public function down(): void + { + Schema::table('backups', function (Blueprint $table) { + $table->unsignedBigInteger('size')->default(0)->nullable(false)->change(); + }); + + Schema::table('snapshots', function (Blueprint $table) { + $table->unsignedBigInteger('size')->default(0)->nullable(false)->change(); + }); + } +}; diff --git a/database/migrations/2024_10_10_194915_update_vmid_column_type_on_servers_table.php b/database/migrations/2024_10_10_194915_update_vmid_column_type_on_servers_table.php new file mode 100644 index 00000000000..c92f451cfc6 --- /dev/null +++ b/database/migrations/2024_10_10_194915_update_vmid_column_type_on_servers_table.php @@ -0,0 +1,22 @@ +unsignedInteger('vmid')->nullable(false)->change(); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->unsignedBigInteger('vmid')->nullable(false)->change(); + }); + } +}; diff --git a/database/migrations/2024_11_14_214143_create_passkeys_table.php b/database/migrations/2024_11_14_214143_create_passkeys_table.php new file mode 100644 index 00000000000..ed98d966c95 --- /dev/null +++ b/database/migrations/2024_11_14_214143_create_passkeys_table.php @@ -0,0 +1,28 @@ +id(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + + $table->string('name'); + $table->string('credential_id'); + $table->json('data'); + + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('created_at')->nullable(); + }); + } + + public function down(): void + { + Schema::dropIfExists('passkeys'); + } +}; diff --git a/database/migrations/2025_01_06_055245_remove_timestamps_from_locations_table.php b/database/migrations/2025_01_06_055245_remove_timestamps_from_locations_table.php new file mode 100644 index 00000000000..e51a41cb23e --- /dev/null +++ b/database/migrations/2025_01_06_055245_remove_timestamps_from_locations_table.php @@ -0,0 +1,24 @@ +dropTimestamps(); + }); + } + + public function down(): void + { + Schema::table('locations', function (Blueprint $table) { + $table->after('description', function (Blueprint $table) { + $table->timestamps(); + }); + }); + } +}; diff --git a/database/migrations/2025_03_28_202855_rename_cluster_column_in_nodes_table.php b/database/migrations/2025_03_28_202855_rename_cluster_column_in_nodes_table.php new file mode 100644 index 00000000000..c89033d7d5b --- /dev/null +++ b/database/migrations/2025_03_28_202855_rename_cluster_column_in_nodes_table.php @@ -0,0 +1,26 @@ +renameColumn('name', 'display_name'); + $table->renameColumn('cluster', 'name'); + $table->string('name')->default(null)->change(); + }); + } + + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->renameColumn('name', 'cluster'); + $table->renameColumn('display_name', 'name'); + $table->string('cluster')->default('proxmox')->change(); + }); + } +}; diff --git a/database/migrations/2025_03_28_212911_rename_secrets_column_in_nodes_table.php b/database/migrations/2025_03_28_212911_rename_secrets_column_in_nodes_table.php new file mode 100644 index 00000000000..2298b2e55e4 --- /dev/null +++ b/database/migrations/2025_03_28_212911_rename_secrets_column_in_nodes_table.php @@ -0,0 +1,22 @@ +renameColumn('secret', 'token_secret'); + }); + } + + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->renameColumn('token_secret', 'secret'); + }); + } +}; diff --git a/database/migrations/2025_03_29_052250_update_columns_in_storage_table.php b/database/migrations/2025_03_29_052250_update_columns_in_storage_table.php new file mode 100644 index 00000000000..c2208f88eb4 --- /dev/null +++ b/database/migrations/2025_03_29_052250_update_columns_in_storage_table.php @@ -0,0 +1,34 @@ +renameColumn('nickname', 'display_name'); + $table->renameColumn('has_kvm', 'stores_kvm'); + $table->renameColumn('has_lxc', 'stores_lxc'); + $table->renameColumn('has_lxc_templates', 'stores_lxc_templates'); + $table->renameColumn('has_backups', 'stores_backups'); + $table->renameColumn('has_iso', 'stores_iso'); + $table->renameColumn('has_snippets', 'stores_snippets'); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + $table->renameColumn('display_name', 'nickname'); + $table->renameColumn('stores_kvm', 'has_kvm'); + $table->renameColumn('stores_lxc', 'has_lxc'); + $table->renameColumn('stores_lxc_templates', 'has_lxc_templates'); + $table->renameColumn('stores_backups', 'has_backups'); + $table->renameColumn('stores_iso', 'has_iso'); + $table->renameColumn('stores_snippets', 'has_snippets'); + }); + } +}; diff --git a/database/migrations/2025_04_01_222350_add_cpu_info_to_nodes_table.php b/database/migrations/2025_04_01_222350_add_cpu_info_to_nodes_table.php new file mode 100644 index 00000000000..a4aa2b46ed4 --- /dev/null +++ b/database/migrations/2025_04_01_222350_add_cpu_info_to_nodes_table.php @@ -0,0 +1,34 @@ +after('token_secret', function (Blueprint $table) { + $table->integer('socket_count'); + $table->integer('core_count'); + $table->integer('cpu_count'); + }); + }); + + DB::table('nodes')->update([ + 'socket_count' => 1, + 'core_count' => 1, + 'cpu_count' => 1, + ]); + } + + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn('socket_count'); + $table->dropColumn('core_count'); + $table->dropColumn('cpu_count'); + }); + } +}; diff --git a/database/migrations/2025_04_05_041601_add_backups_sort_order_to_storage_to_node_table.php b/database/migrations/2025_04_05_041601_add_backups_sort_order_to_storage_to_node_table.php new file mode 100644 index 00000000000..71082d6732e --- /dev/null +++ b/database/migrations/2025_04_05_041601_add_backups_sort_order_to_storage_to_node_table.php @@ -0,0 +1,51 @@ +integer('backup_order')->nullable()->after('node_id'); + }); + + // automatically add the backup_order column to existing records that can store backups. make sure to scope by node + DB::transaction(function () { + // Get all nodes to scope by node + $nodes = DB::table('nodes')->get(['id']); + + foreach ($nodes as $node) { + // Get all storage records for this node that can store backups + $storages = DB::table('storage_to_node') + ->select('storage_to_node.storage_id', 'storage_to_node.node_id') + ->join('storages', 'storage_to_node.storage_id', '=', 'storages.id') + ->where('storage_to_node.node_id', $node->id) + ->where('storages.stores_backups', true) // Using the new column name from the previous migration + ->orderBy('storages.id') // Order by ID to provide consistent results + ->get(); + + // Assign incrementing backup_order to each storage + $order = 1; + foreach ($storages as $storage) { + DB::table('storage_to_node') + ->where('storage_id', $storage->storage_id) + ->where('node_id', $storage->node_id) + ->update(['backup_order' => $order]); + + $order++; + } + } + }); + } + + public function down(): void + { + Schema::table('storage_to_node', function (Blueprint $table) { + $table->dropColumn('backup_order'); + }); + } +}; diff --git a/database/migrations/2025_05_05_042408_create_network_interfaces_table.php b/database/migrations/2025_05_05_042408_create_network_interfaces_table.php new file mode 100644 index 00000000000..10f796dab86 --- /dev/null +++ b/database/migrations/2025_05_05_042408_create_network_interfaces_table.php @@ -0,0 +1,68 @@ +id(); + $table->foreignId('node_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->string('description')->nullable(); + }); + + // Migrate existing network values to the new network_interfaces table + DB::transaction(function () { + $nodes = DB::table('nodes')->whereNotNull('network')->get(); + + foreach ($nodes as $node) { + // Create a network interface with the network value from the node + DB::table('network_interfaces')->insert([ + 'node_id' => $node->id, + 'name' => $node->network, + 'description' => 'Migrated from node settings', + ]); + } + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn('network'); + }); + } + + public function down(): void + { + // First, get the first network interface for each node and store its name in the network field + Schema::table('nodes', function (Blueprint $table) { + $table->string('network')->nullable()->after('memory_overallocate'); + }); + + // Populate the network field with the first network interface name for each node + DB::table('nodes') + ->select('nodes.id as node_id', 'network_interfaces.name as interface_name') + ->leftJoin('network_interfaces', 'nodes.id', '=', 'network_interfaces.node_id') + ->orderBy('network_interfaces.id') + ->get() + ->groupBy('node_id') + ->each(function ($nodes) { + $first = $nodes->first(); + if ($first && isset($first->interface_name)) { + DB::table('nodes') + ->where('id', $first->node_id) + ->update(['network' => $first->interface_name]); + } + }); + + // Make the network field non-nullable + Schema::table('nodes', function (Blueprint $table) { + $table->string('network')->nullable(false)->change(); + }); + + Schema::dropIfExists('network_interfaces'); + } +}; diff --git a/database/migrations/2025_05_07_194624_ipam_revision.php b/database/migrations/2025_05_07_194624_ipam_revision.php new file mode 100644 index 00000000000..82fe969f742 --- /dev/null +++ b/database/migrations/2025_05_07_194624_ipam_revision.php @@ -0,0 +1,252 @@ +renameColumn('address_pool_id', 'address_block_group_id'); + $table->unsignedBigInteger('network_interface_id')->nullable()->after('node_id'); + // Use a descriptive but shorter name for the foreign key constraint + $table->foreign('network_interface_id', 'address_block_network_interface_foreign') + ->references('id') + ->on('network_interfaces') + ->onDelete('cascade'); + }); + + /** + * Fill the network_interface_id column with the first network interface of the node. + */ + DB::table('address_block_group_to_network_interface') + ->select('address_block_group_to_network_interface.address_block_group_id', + 'address_block_group_to_network_interface.node_id', + 'network_interfaces.id as interface_id') + ->join('network_interfaces', 'address_block_group_to_network_interface.node_id', '=', 'network_interfaces.node_id') + ->whereNull('address_block_group_to_network_interface.network_interface_id') + ->orderBy('network_interfaces.id') + ->get() + ->groupBy(function ($item) { + return $item->address_block_group_id.'-'.$item->node_id; + }) + ->each(function ($records) { + $first = $records->first(); + if ($first && isset($first->interface_id)) { + DB::table('address_block_group_to_network_interface') + ->where('address_block_group_id', $first->address_block_group_id) + ->where('node_id', $first->node_id) + ->update(['network_interface_id' => $first->interface_id]); + } + }); + + // Make network_interface_id non-nullable and remove node_id constraint + Schema::table('address_block_group_to_network_interface', function (Blueprint $table) { + // Make network_interface_id non-nullable + $table->foreignId('network_interface_id')->nullable(false)->change(); + + $table->dropForeign('address_pool_to_node_node_id_foreign'); + $table->dropColumn('node_id'); + }); + + Schema::table('address_block_groups', function (Blueprint $table) { + $table->string('description')->nullable()->after('name'); + }); + + Schema::create('address_blocks', function (Blueprint $table) { + $table->id(); + $table->foreignId('address_block_group_id')->constrained()->cascadeOnDelete(); + $table->string('name')->nullable(); + $table->string('description')->nullable(); + $table->string('version'); + $table->string('base_ip'); + $table->string('gateway')->nullable(); + $table->string('mac_address')->nullable(); + $table->integer('prefix_length_from'); + $table->integer('prefix_length_to'); + }); + + Schema::table('addresses', function (Blueprint $table) { + $table->foreignId('address_block_id')->after('address_pool_id')->nullable()->constrained()->cascadeOnDelete(); + $table->renameColumn('address', 'ip'); + $table->renameColumn('cidr', 'prefix_length'); + + $table->unique(['address_block_id', 'ip']); + }); + + // Previously IPAM was this structure: IPs belong to Address Pools. Address Pools can be connected to nodes + // Now we have a new structure: IPs belong to Address Blocks. Address Blocks belong to Address Block Groups. Address Block Groups can be connected to nodes. + // So we need to migrate the data. + // In each former address pool, organize the IPs into address blocks. Then, create a new address block group for each address pool. + // Please refrain from using raw SQL so that its cross database compatibility is guaranteed. Use the DB facade instead. + + DB::transaction(callback: function () { + // Define columns needed for selection and grouping + $selectColumns = ['address_pool_id', 'gateway', 'prefix_length', 'type', 'mac_address', 'ip', 'id']; + $groupByColumns = ['address_pool_id', 'gateway', 'prefix_length', 'type', 'mac_address']; + + // Fetch addresses and group them by a composite key + $potentialBlocks = DB::table('addresses') + ->select($selectColumns) + ->whereNotNull('address_pool_id') // Only migrate addresses that belonged to a pool + ->orderBy('id') // Consistent ordering helps grouping + ->get() + // Group by a generated composite key string instead of an array + ->groupBy(function ($item) use ($groupByColumns) { + $keyParts = []; + foreach ($groupByColumns as $col) { + // Use 'NULL_VALUE' or similar for actual nulls to make key distinct + $keyParts[] = $item->{$col} ?? 'NULL_VALUE'; + } + + // Use a separator unlikely to appear in the data itself + return implode('||', $keyParts); + }); + + // Get all address block groups (formerly pools) to map IDs and get descriptions + $addressBlockGroups = DB::table('address_block_groups')->get()->keyBy('id'); + + /** + * Iterate through the groups (key is the composite string, value is the collection) + */ + foreach ($potentialBlocks as $compositeKey => $addressesInBlock) { + /** @var Collection $addressesInBlock */ + // $addressesInBlock is now the final collection for this group + $firstAddress = $addressesInBlock->first(); + if (! $firstAddress) { + continue; + } // Skip if group is somehow empty + + // Now access properties directly from the first item in the group + $oldPoolId = $firstAddress->address_pool_id; + $gateway = $firstAddress->gateway ? IPFactory::parseAddressString($firstAddress->gateway)->toString() : null; + $prefixLength = $firstAddress->prefix_length; + $version = $firstAddress->type; + $macAddress = $firstAddress->mac_address; + $firstIp = $firstAddress->ip; + + $group = $addressBlockGroups->get($oldPoolId); + if (! $group) { + throw new RuntimeException("Migration Error: Address Block Group (formerly Pool) with ID {$oldPoolId} not found during migration (composite key: {$compositeKey}). Cannot migrate addresses associated with it."); + } + + // Create a new address_block record + try { + // Attempt to parse the range using the correct Factory method + // Use the first IP and prefix length to define the subnet range + $range = IPFactory::parseRangeString($firstIp.'/'.$prefixLength); + if ($range) { + // Get the network address (start address of the range) + $baseIp = $range->getStartAddress()->toString(); + $blockName = "Migrated Block ({$baseIp}/{$prefixLength})"; + } else { + throw new RuntimeException("Migration Error: Failed to parse range for {$firstIp}/{$prefixLength} using ip-lib (composite key: {$compositeKey})."); + } + } catch (Exception $e) { + throw new RuntimeException("Migration Error: Could not calculate base IP for {$firstIp}/{$prefixLength} during migration (composite key: {$compositeKey}): ".$e->getMessage()); + } + + $newBlockId = DB::table('address_blocks')->insertGetId([ + 'address_block_group_id' => $group->id, + 'name' => $blockName, + 'description' => $group->description, + 'version' => $version, + 'base_ip' => $baseIp, + 'gateway' => $gateway, + 'mac_address' => $macAddress, + 'prefix_length_from' => $prefixLength, + 'prefix_length_to' => $prefixLength, + ]); + + // Update all addresses belonging to this specific group + $addressIdsToUpdate = $addressesInBlock->pluck('id')->toArray(); + + if (! empty($addressIdsToUpdate)) { + DB::table('addresses') + ->whereIn('id', $addressIdsToUpdate) + ->update(['address_block_id' => $newBlockId]); + } + } + }); + + Schema::table('addresses', function (Blueprint $table) { + if (DB::table('addresses')->whereNull('address_block_id')->exists()) { + throw new RuntimeException('Migration Error: Not all addresses could be assigned to an address block. Cannot make address_block_id non-nullable..'); + } + + $table->dropForeign('ip_addresses_address_pool_id_foreign'); // some shenanigans because Laravel can't predict the name as we fucked it all up. + $table->dropColumn('address_pool_id'); + + $table->foreignId('address_block_id')->nullable(false)->change(); + + $table->dropColumn('type', 'gateway', 'mac_address', 'created_at', 'updated_at'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // --- Clear Addresses Data --- + DB::table('addresses')->truncate(); + + // --- Reverse Final Schema Cleanup --- + Schema::table('addresses', function (Blueprint $table) { + // Re-add columns (nullable for safety during rollback) + $table->foreignId('address_pool_id')->after('id')->constrained('address_block_groups'); + $table->string('type')->nullable(); + $table->string('gateway')->nullable(); + $table->string('mac_address')->nullable(); + $table->timestamps(); // Re-add timestamps + + // Drop the new foreign key (constraint first, then column) + $table->dropForeign(['address_block_id']); + $table->dropColumn('address_block_id'); + + // Rename columns back + $table->renameColumn('ip', 'address'); + $table->renameColumn('prefix_length', 'cidr'); + }); + + // --- Reverse New Table Creation --- + Schema::dropIfExists('address_blocks'); + + // --- Reverse Preparations --- + Schema::table('address_block_groups', function (Blueprint $table) { + $table->dropColumn('description'); + }); + + // Purge all records from address_block_group_to_network_interface + DB::table('address_block_group_to_network_interface')->truncate(); + + // Revert schema changes to address_block_group_to_network_interface + Schema::table('address_block_group_to_network_interface', function (Blueprint $table) { + // Drop network_interface_id column + $table->dropConstrainedForeignId('network_interface_id'); + + // Restore node_id foreign key + $table->foreign('node_id')->references('id')->on('nodes')->onDelete('cascade'); + + // Rename the column back + $table->renameColumn('address_block_group_id', 'address_pool_id'); + }); + + // --- Reverse Renames --- + Schema::rename('addresses', 'ip_addresses'); + Schema::rename('address_block_group_to_network_interface', 'address_pool_to_node'); + Schema::rename('address_block_groups', 'address_pools'); + } +}; diff --git a/database/migrations/2025_05_29_030213_add_primary_ips_to_servers_table.php b/database/migrations/2025_05_29_030213_add_primary_ips_to_servers_table.php new file mode 100644 index 00000000000..1e43e53a8f6 --- /dev/null +++ b/database/migrations/2025_05_29_030213_add_primary_ips_to_servers_table.php @@ -0,0 +1,33 @@ +after('disk', function (Blueprint $table) { + $table->foreignId('primary_ipv4_address_id') + ->nullable() + ->constrained('addresses') + ->nullOnDelete(); + + $table->foreignId('primary_ipv6_address_id') + ->nullable() + ->constrained('addresses') + ->nullOnDelete(); + }); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->dropConstrainedForeignId('primary_ipv4_address_id'); + $table->dropConstrainedForeignId('primary_ipv6_address_id'); + }); + } +}; diff --git a/database/migrations/2025_06_15_172736_templates_overhaul.php b/database/migrations/2025_06_15_172736_templates_overhaul.php new file mode 100644 index 00000000000..136e16c7804 --- /dev/null +++ b/database/migrations/2025_06_15_172736_templates_overhaul.php @@ -0,0 +1,93 @@ +dropForeign(['template_group_id']); + }); + + Schema::table('deployments', function (Blueprint $table) { + $table->dropForeign(['template_id']); + }); + + // Now we can safely truncate both tables + DB::table('templates')->truncate(); + DB::table('template_groups')->truncate(); + + // Re-add the foreign key constraints + Schema::table('templates', function (Blueprint $table) { + $table->foreign('template_group_id')->references('id')->on('template_groups')->onDelete('cascade'); + }); + + Schema::table('deployments', function (Blueprint $table) { + $table->foreign('template_id')->references('id')->on('templates')->onDelete('cascade'); + }); + + Schema::table('template_groups', function (Blueprint $table) { + $table->dropConstrainedForeignId('node_id'); + $table->after('name', function (Blueprint $table) { + $table->text('description')->nullable(); + $table->string('icon')->nullable(); + }); + $table->renameColumn('hidden', 'is_admin_only'); + $table->dropColumn('order_column'); + $table->dropTimestamps(); + }); + + Schema::table('templates', function (Blueprint $table) { + $table->text('description')->nullable()->after('name'); + $table->renameColumn('hidden', 'is_admin_only'); + $table->dropColumn('order_column'); + $table->dropTimestamps(); + }); + } + + public function down(): void + { + // First drop all foreign key constraints + Schema::table('templates', function (Blueprint $table) { + $table->dropForeign(['template_group_id']); + }); + + Schema::table('deployments', function (Blueprint $table) { + $table->dropForeign(['template_id']); + }); + + // Now we can safely truncate both tables + DB::table('templates')->truncate(); + DB::table('template_groups')->truncate(); + + // Re-add the foreign key constraints + Schema::table('templates', function (Blueprint $table) { + $table->foreign('template_group_id')->references('id')->on('template_groups')->onDelete('cascade'); + }); + + Schema::table('deployments', function (Blueprint $table) { + $table->foreign('template_id')->references('id')->on('templates')->onDelete('cascade'); + }); + + Schema::table('template_groups', function (Blueprint $table) { + $table->foreignId('node_id')->constrained()->cascadeOnDelete(); + $table->dropColumn('description'); + $table->dropColumn('icon'); + $table->renameColumn('is_admin_only', 'hidden'); + $table->unsignedBigInteger('order_column')->after('hidden'); + $table->timestamps(); + }); + + Schema::table('templates', function (Blueprint $table) { + $table->dropColumn('description'); + $table->renameColumn('is_admin_only', 'hidden'); + $table->unsignedBigInteger('order_column')->after('hidden'); + $table->timestamps(); + }); + } +}; diff --git a/database/migrations/2025_07_22_183612_make_server_status_nonnullable.php b/database/migrations/2025_07_22_183612_make_server_status_nonnullable.php new file mode 100644 index 00000000000..042c027191b --- /dev/null +++ b/database/migrations/2025_07_22_183612_make_server_status_nonnullable.php @@ -0,0 +1,26 @@ +whereNull('status')->update(['status' => 'ready']); + + Schema::table('servers', function (Blueprint $table) { + $table->string('status')->default('ready')->change(); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->string('status')->nullable()->change(); + }); + } +}; diff --git a/database/migrations/2025_08_17_213210_overhaul_deployments_table.php b/database/migrations/2025_08_17_213210_overhaul_deployments_table.php new file mode 100644 index 00000000000..f6e8c644b35 --- /dev/null +++ b/database/migrations/2025_08_17_213210_overhaul_deployments_table.php @@ -0,0 +1,70 @@ +dropColumn([ + 'should_create_vm', + 'delete_successful', + 'deleted_vm_at', + 'build_successful', + 'build_progress', + 'built_vm_at', + 'sync_successful', + 'synced_vm_at', + 'created_at', + ]); + + $table->after('template_id', function (Blueprint $table) { + $table->string('type'); + $table->string('status'); + }); + + $table->after('start_on_completion', function (Blueprint $table) { + $table->timestamp('requested_at'); + $table->timestamp('completed_at')->nullable(); + }); + }); + + Schema::create('deployment_steps', function (Blueprint $table) { + $table->id(); + $table->foreignId('deployment_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->string('status'); + $table->bigInteger('progress_total')->nullable(); + $table->bigInteger('progress_current')->default(0); + $table->timestamp('started_at')->nullable(); + $table->timestamp('completed_at')->nullable(); + $table->string('error_code')->nullable(); + $table->text('error_message')->nullable(); + }); + } + + public function down(): void + { + Schema::table('deployments', function (Blueprint $table) { + $table->dropColumn(['type', 'status', 'requested_at', 'completed_at']); + + $table->boolean('should_create_vm')->after('template_id'); + + $table->after('start_on_completion', function (Blueprint $table) { + $table->boolean('delete_successful'); + $table->timestamp('deleted_vm_at')->nullable(); + $table->boolean('build_successful'); + $table->integer('build_progress'); + $table->timestamp('built_vm_at')->nullable(); + $table->boolean('sync_successful'); + $table->timestamp('synced_vm_at')->nullable(); + $table->timestamp('created_at')->nullable(); + }); + }); + + Schema::dropIfExists('deployment_steps'); + } +}; diff --git a/database/migrations/2026_03_10_000000_remove_snapshots_feature.php b/database/migrations/2026_03_10_000000_remove_snapshots_feature.php new file mode 100644 index 00000000000..9e5a25c3ae7 --- /dev/null +++ b/database/migrations/2026_03_10_000000_remove_snapshots_feature.php @@ -0,0 +1,39 @@ +dropColumn(['snapshot_count_limit', 'snapshot_size_limit']); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->integer('snapshot_count_limit')->after('disk'); + $table->integer('snapshot_size_limit')->after('snapshot_count_limit'); + }); + + Schema::create('snapshots', function (Blueprint $table) { + $table->id(); + $table->uuid()->unique(); + $table->foreignId('server_id')->constrained()->cascadeOnDelete(); + $table->foreignId('snapshot_id')->nullable()->constrained('snapshots')->cascadeOnDelete(); + $table->string('name'); + $table->string('description')->nullable(); + $table->boolean('is_locked')->default(false); + $table->string('errors')->nullable(); + $table->unsignedInteger('size')->nullable(false); + $table->timestamp('completed_at')->nullable(); + $table->timestamp('created_at')->nullable(); + }); + } +}; diff --git a/database/migrations/2026_07_06_000000_split_backup_errors_into_code_and_message.php b/database/migrations/2026_07_06_000000_split_backup_errors_into_code_and_message.php new file mode 100644 index 00000000000..f2a5113ebd6 --- /dev/null +++ b/database/migrations/2026_07_06_000000_split_backup_errors_into_code_and_message.php @@ -0,0 +1,51 @@ +string('error_code')->nullable()->after('errors'); + $table->string('error_message')->nullable()->after('error_code'); + }); + + // Migrate the old free-text `errors` into the code + message pair: + // the raw text becomes the message, classified into a stable code. + DB::table('backups')->whereNotNull('errors')->orderBy('id') + ->each(function (object $backup) { + DB::table('backups')->where('id', $backup->id)->update([ + 'error_code' => BackupErrorCode::classify($backup->errors)->value, + 'error_message' => $backup->errors, + ]); + }); + + Schema::table('backups', function (Blueprint $table) { + $table->dropColumn('errors'); + }); + } + + public function down(): void + { + Schema::table('backups', function (Blueprint $table) { + $table->string('errors')->nullable()->after('description'); + }); + + // Recombine: prefer the human-readable message, fall back to the code. + DB::table('backups')->whereNotNull('error_code')->orderBy('id') + ->each(function (object $backup) { + DB::table('backups')->where('id', $backup->id)->update([ + 'errors' => $backup->error_message ?? $backup->error_code, + ]); + }); + + Schema::table('backups', function (Blueprint $table) { + $table->dropColumn(['error_code', 'error_message']); + }); + } +}; diff --git a/database/migrations/2026_07_07_000000_convert_ip_columns_to_inet.php b/database/migrations/2026_07_07_000000_convert_ip_columns_to_inet.php new file mode 100644 index 00000000000..cca706a5939 --- /dev/null +++ b/database/migrations/2026_07_07_000000_convert_ip_columns_to_inet.php @@ -0,0 +1,39 @@ +change() can't convert text -> inet (Postgres needs an explicit USING + // cast), so issue the ALTERs directly. The stored values are already valid IP strings. + DB::statement('ALTER TABLE addresses ALTER COLUMN ip TYPE INET USING ip::inet'); + DB::statement('ALTER TABLE address_blocks ALTER COLUMN base_ip TYPE INET USING base_ip::inet'); + DB::statement('ALTER TABLE address_blocks ALTER COLUMN gateway TYPE INET USING gateway::inet'); + + // Partial index backing the allocator's hot path: + // WHERE address_block_id = ? AND server_id IS NULL ORDER BY ip LIMIT n + // Only free rows are indexed (so it shrinks as IPs get assigned), and because ip is now + // stored in inet order the ORDER BY is served by the index with no sort. This is what + // makes finding the next free address O(log N + n) instead of a table scan. + DB::statement('CREATE INDEX addresses_free_by_block_ip_idx ON addresses (address_block_id, ip) WHERE server_id IS NULL'); + } + + public function down(): void + { + DB::statement('DROP INDEX IF EXISTS addresses_free_by_block_ip_idx'); + + // host() renders an inet back to its bare address string for the varchar columns. + DB::statement('ALTER TABLE addresses ALTER COLUMN ip TYPE VARCHAR(255) USING host(ip)'); + DB::statement('ALTER TABLE address_blocks ALTER COLUMN base_ip TYPE VARCHAR(255) USING host(base_ip)'); + DB::statement('ALTER TABLE address_blocks ALTER COLUMN gateway TYPE VARCHAR(255) USING host(gateway)'); + } +}; diff --git a/database/migrations/2026_07_07_000002_add_state_to_addresses.php b/database/migrations/2026_07_07_000002_add_state_to_addresses.php new file mode 100644 index 00000000000..db9c49eac3a --- /dev/null +++ b/database/migrations/2026_07_07_000002_add_state_to_addresses.php @@ -0,0 +1,38 @@ +string('state')->default('available')->after('server_id'); + }); + + // Backfill from the pre-existing signal: an attached address is 'assigned', the rest 'available'. + DB::table('addresses')->whereNotNull('server_id')->update(['state' => 'assigned']); + + // The allocator now selects on state, so repoint the partial index from server_id to state. + DB::statement('DROP INDEX IF EXISTS addresses_free_by_block_ip_idx'); + DB::statement("CREATE INDEX addresses_available_by_block_ip_idx ON addresses (address_block_id, ip) WHERE state = 'available'"); + } + + public function down(): void + { + DB::statement('DROP INDEX IF EXISTS addresses_available_by_block_ip_idx'); + DB::statement('CREATE INDEX addresses_free_by_block_ip_idx ON addresses (address_block_id, ip) WHERE server_id IS NULL'); + + Schema::table('addresses', function (Blueprint $table) { + $table->dropColumn('state'); + }); + } +}; diff --git a/database/migrations/2026_07_07_000003_create_system_actor_and_token_ownership.php b/database/migrations/2026_07_07_000003_create_system_actor_and_token_ownership.php new file mode 100644 index 00000000000..07dfbb6df8f --- /dev/null +++ b/database/migrations/2026_07_07_000003_create_system_actor_and_token_ownership.php @@ -0,0 +1,45 @@ +id(); + $table->string('name')->default('System'); + $table->timestamps(); + }); + + // The singleton the application tokens hang off of. + DB::table('system_actors')->insert([ + 'name' => 'System', + 'created_at' => now(), + 'updated_at' => now(), + ]); + + Schema::table('personal_access_tokens', function (Blueprint $table) { + $table->foreignId('created_by')->nullable()->after('type') + ->constrained('users')->nullOnDelete(); + }); + } + + public function down(): void + { + Schema::table('personal_access_tokens', function (Blueprint $table) { + $table->dropConstrainedForeignId('created_by'); + }); + + Schema::dropIfExists('system_actors'); + } +}; diff --git a/database/migrations/2026_07_07_100000_add_reserved_bytes_to_storages_table.php b/database/migrations/2026_07_07_100000_add_reserved_bytes_to_storages_table.php new file mode 100644 index 00000000000..4496342f479 --- /dev/null +++ b/database/migrations/2026_07_07_100000_add_reserved_bytes_to_storages_table.php @@ -0,0 +1,28 @@ +unsignedBigInteger('reserved_bytes')->nullable()->after('size'); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + $table->dropColumn('reserved_bytes'); + }); + } +}; diff --git a/database/migrations/2026_07_07_110000_create_server_disks_table.php b/database/migrations/2026_07_07_110000_create_server_disks_table.php new file mode 100644 index 00000000000..28871f6a2c5 --- /dev/null +++ b/database/migrations/2026_07_07_110000_create_server_disks_table.php @@ -0,0 +1,57 @@ +storage`). + * A later slice turns them into `primaryDisk()` accessors and drops them. + * `size` is MiB (StorageSizeCast), matching `servers.disk`. `interface` + * (e.g. `scsi1`) is assigned at build time, so it's null until then. + */ + public function up(): void + { + Schema::create('server_disks', function (Blueprint $table) { + $table->id(); + $table->foreignId('server_id')->constrained()->cascadeOnDelete(); + $table->foreignId('storage_id')->constrained(); + $table->unsignedBigInteger('size'); + $table->string('interface')->nullable(); + $table->boolean('is_primary')->default(false); + $table->unsignedInteger('disk_index')->default(0); + + // A server has at most one primary disk, and never two disks on the + // same interface slot (once assigned). + $table->unique(['server_id', 'interface']); + }); + + // Backfill: every existing server gets a primary disk row from its + // current (storage_id, disk). Both `disk` and `size` are MiB, so copy + // straight across. + DB::table('server_disks')->insertUsing( + ['server_id', 'storage_id', 'size', 'interface', 'is_primary', 'disk_index'], + DB::table('servers')->select( + 'id', + 'storage_id', + 'disk', + DB::raw('NULL as interface'), + DB::raw('true as is_primary'), + DB::raw('0 as disk_index'), + ), + ); + } + + public function down(): void + { + Schema::dropIfExists('server_disks'); + } +}; diff --git a/database/migrations/2026_07_08_000001_create_session_records_table.php b/database/migrations/2026_07_08_000001_create_session_records_table.php new file mode 100644 index 00000000000..d2372645cb2 --- /dev/null +++ b/database/migrations/2026_07_08_000001_create_session_records_table.php @@ -0,0 +1,32 @@ +id(); + $table->string('session_id')->unique(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->timestamp('last_active_at'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('session_records'); + } +}; diff --git a/database/migrations/2026_07_09_000000_add_vlan_support_to_network_interfaces.php b/database/migrations/2026_07_09_000000_add_vlan_support_to_network_interfaces.php new file mode 100644 index 00000000000..7a5f6689e74 --- /dev/null +++ b/database/migrations/2026_07_09_000000_add_vlan_support_to_network_interfaces.php @@ -0,0 +1,36 @@ +boolean('is_vlan_aware')->default(false); + $table->unsignedSmallInteger('vlan_tag')->nullable(); + }); + + Schema::table('servers', function (Blueprint $table) { + $table->foreignId('network_interface_id') + ->nullable() + ->constrained('network_interfaces') + ->nullOnDelete(); + $table->unsignedSmallInteger('vlan_tag')->nullable(); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->dropConstrainedForeignId('network_interface_id'); + $table->dropColumn('vlan_tag'); + }); + + Schema::table('network_interfaces', function (Blueprint $table) { + $table->dropColumn(['is_vlan_aware', 'vlan_tag']); + }); + } +}; diff --git a/database/migrations/2026_07_10_000000_create_oauth_connections_table.php b/database/migrations/2026_07_10_000000_create_oauth_connections_table.php new file mode 100644 index 00000000000..bb5c84da6a1 --- /dev/null +++ b/database/migrations/2026_07_10_000000_create_oauth_connections_table.php @@ -0,0 +1,35 @@ +id(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + $table->string('provider'); + $table->string('provider_id'); + $table->string('name')->nullable(); + $table->string('email')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamps(); + + $table->unique(['provider', 'provider_id']); + }); + } + + public function down(): void + { + Schema::dropIfExists('oauth_connections'); + } +}; diff --git a/database/migrations/2026_07_12_160000_add_bandwidth_controls_to_servers_and_nodes.php b/database/migrations/2026_07_12_160000_add_bandwidth_controls_to_servers_and_nodes.php new file mode 100644 index 00000000000..7068ea6e64f --- /dev/null +++ b/database/migrations/2026_07_12_160000_add_bandwidth_controls_to_servers_and_nodes.php @@ -0,0 +1,48 @@ + node -> BandwidthSettings global). + * - servers.bandwidth_reset_day day-of-month (1-31) the monthly quota resets on, + * seeded from created_at. Null falls back to + * created_at at runtime. + */ +return new class extends Migration +{ + public function up(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->unsignedBigInteger('speed_limit')->nullable()->after('bandwidth_limit'); + $table->json('overage_penalty')->nullable()->after('speed_limit'); + $table->unsignedTinyInteger('bandwidth_reset_day')->nullable()->after('overage_penalty'); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->json('overage_penalty')->nullable()->after('memory_overallocate'); + }); + + // Seed the reset anchor from each server's creation day (postgres). + DB::statement('UPDATE servers SET bandwidth_reset_day = EXTRACT(DAY FROM created_at)'); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn(['speed_limit', 'overage_penalty', 'bandwidth_reset_day']); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn('overage_penalty'); + }); + } +}; diff --git a/database/migrations/2026_07_15_000001_add_allowed_networks_to_personal_access_tokens_table.php b/database/migrations/2026_07_15_000001_add_allowed_networks_to_personal_access_tokens_table.php new file mode 100644 index 00000000000..59aa972502f --- /dev/null +++ b/database/migrations/2026_07_15_000001_add_allowed_networks_to_personal_access_tokens_table.php @@ -0,0 +1,24 @@ +jsonb('allowed_networks')->nullable()->after('abilities'); + }); + } + + public function down(): void + { + Schema::table('personal_access_tokens', function (Blueprint $table) { + $table->dropColumn('allowed_networks'); + }); + } +}; diff --git a/database/migrations/2026_07_15_000002_add_two_factor_confirmed_at_to_users_table.php b/database/migrations/2026_07_15_000002_add_two_factor_confirmed_at_to_users_table.php new file mode 100644 index 00000000000..ee2e682a8a9 --- /dev/null +++ b/database/migrations/2026_07_15_000002_add_two_factor_confirmed_at_to_users_table.php @@ -0,0 +1,54 @@ +timestamp('two_factor_confirmed_at') + ->after('two_factor_recovery_codes') + ->nullable(); + }); + } + + // Anyone who already set two factor up did so under the old rule, where + // holding a secret *was* being enabled. Now that enabled means + // confirmed, leaving their timestamp null would read as "no second + // factor" and quietly stop challenging them at login — a downgrade none + // of them asked for. Treat an existing secret as already confirmed. + DB::table('users') + ->whereNotNull('two_factor_secret') + ->whereNull('two_factor_confirmed_at') + ->update(['two_factor_confirmed_at' => now()]); + } + + public function down(): void + { + if (! Schema::hasColumn('users', 'two_factor_confirmed_at')) { + return; + } + + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('two_factor_confirmed_at'); + }); + } +}; diff --git a/database/migrations/2026_07_15_000003_issue_recovery_codes_to_passkey_users.php b/database/migrations/2026_07_15_000003_issue_recovery_codes_to_passkey_users.php new file mode 100644 index 00000000000..a3a5d7dbf21 --- /dev/null +++ b/database/migrations/2026_07_15_000003_issue_recovery_codes_to_passkey_users.php @@ -0,0 +1,36 @@ +whereNull('two_factor_recovery_codes') + ->whereExists(fn ($query) => $query + ->selectRaw('1') + ->from('passkeys') + ->whereColumn('passkeys.user_id', 'users.id')) + ->orderBy('id') + ->eachById(function ($user) { + DB::table('users') + ->where('id', $user->id) + ->update([ + 'two_factor_recovery_codes' => Fortify::currentEncrypter()->encrypt( + json_encode(Collection::times(8, fn () => RecoveryCode::generate())->all()), + ), + ]); + }); + } + + /** Recovery codes are user-held secrets; a rollback must not silently revoke them. */ + public function down(): void + { + // Irreversible data migration. + } +}; diff --git a/database/migrations/2026_07_17_000000_add_task_upid_to_deployment_steps.php b/database/migrations/2026_07_17_000000_add_task_upid_to_deployment_steps.php new file mode 100644 index 00000000000..6c3252d9619 --- /dev/null +++ b/database/migrations/2026_07_17_000000_add_task_upid_to_deployment_steps.php @@ -0,0 +1,29 @@ +string('task_upid')->nullable()->after('status'); + }); + } + + public function down(): void + { + Schema::table('deployment_steps', function (Blueprint $table) { + $table->dropColumn('task_upid'); + }); + } +}; diff --git a/database/migrations/2026_07_17_000001_add_status_tracking_to_nodes_table.php b/database/migrations/2026_07_17_000001_add_status_tracking_to_nodes_table.php new file mode 100644 index 00000000000..7c1e70ffa8a --- /dev/null +++ b/database/migrations/2026_07_17_000001_add_status_tracking_to_nodes_table.php @@ -0,0 +1,50 @@ +string('status')->default(NodeStatus::UNKNOWN->value)->after('verify_tls'); + // The classified ConnectionErrorCode: why it is unreachable, not just that it is. + $table->string('status_code')->nullable()->after('status'); + // The raw error, kept for the details disclosure the UI already has. + $table->text('status_message')->nullable()->after('status_code'); + // Last *successful* contact -- what staleness is measured from. + $table->timestamp('last_seen_at')->nullable()->after('status_message'); + // Last attempt, successful or not. + $table->timestamp('status_checked_at')->nullable()->after('last_seen_at'); + // Debounce counter so a single flap never alerts (slice 3). + $table->unsignedInteger('consecutive_failures')->default(0)->after('status_checked_at'); + }); + } + + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn([ + 'status', + 'status_code', + 'status_message', + 'last_seen_at', + 'status_checked_at', + 'consecutive_failures', + ]); + }); + } +}; diff --git a/database/migrations/2026_07_17_000002_add_progress_polish_to_deployments.php b/database/migrations/2026_07_17_000002_add_progress_polish_to_deployments.php new file mode 100644 index 00000000000..5d551f2eb2a --- /dev/null +++ b/database/migrations/2026_07_17_000002_add_progress_polish_to_deployments.php @@ -0,0 +1,44 @@ +string('progress_mode')->default('indeterminate')->after('status'); + $table->unsignedInteger('sequence')->default(0)->after('progress_mode'); + }); + + Schema::table('deployments', function (Blueprint $table) { + $table->timestamp('started_at')->nullable()->after('requested_at'); + }); + } + + public function down(): void + { + Schema::table('deployment_steps', function (Blueprint $table) { + $table->dropColumn(['progress_mode', 'sequence']); + }); + + Schema::table('deployments', function (Blueprint $table) { + $table->dropColumn('started_at'); + }); + } +}; diff --git a/database/migrations/2026_07_17_010000_replace_coterm_with_anchor.php b/database/migrations/2026_07_17_010000_replace_coterm_with_anchor.php new file mode 100644 index 00000000000..0f837fbb0ab --- /dev/null +++ b/database/migrations/2026_07_17_010000_replace_coterm_with_anchor.php @@ -0,0 +1,58 @@ +id(); + $table->uuid('uuid')->unique(); + $table->string('name'); + $table->string('mode'); + $table->string('public_url'); + $table->text('secret'); + $table->foreignId('relay_id')->nullable()->constrained('anchors')->nullOnDelete(); + $table->string('enrollment_token_hash', 64)->nullable()->unique(); + $table->timestamp('enrollment_expires_at')->nullable(); + $table->timestamp('enrolled_at')->nullable(); + $table->timestamp('last_seen_at')->nullable(); + $table->string('version')->nullable(); + $table->unsignedSmallInteger('protocol_min')->nullable(); + $table->unsignedSmallInteger('protocol_max')->nullable(); + $table->json('capabilities')->nullable(); + $table->timestamps(); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->dropConstrainedForeignId('coterm_id'); + $table->foreignId('anchor_id')->nullable()->constrained()->nullOnDelete(); + }); + + Schema::dropIfExists('coterms'); + } + + public function down(): void + { + Schema::create('coterms', function (Blueprint $table) { + $table->id(); + $table->string('name'); + $table->boolean('is_tls_enabled')->default(true); + $table->string('fqdn'); + $table->integer('port')->default(443); + $table->string('token_id')->unique(); + $table->text('token'); + $table->timestamps(); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->dropConstrainedForeignId('anchor_id'); + $table->foreignId('coterm_id')->nullable()->constrained()->nullOnDelete(); + }); + + Schema::dropIfExists('anchors'); + } +}; diff --git a/database/migrations/2026_07_24_000000_add_state_reason_to_addresses.php b/database/migrations/2026_07_24_000000_add_state_reason_to_addresses.php new file mode 100644 index 00000000000..c195af8b434 --- /dev/null +++ b/database/migrations/2026_07_24_000000_add_state_reason_to_addresses.php @@ -0,0 +1,63 @@ +string('state_reason')->nullable()->after('state'); + }); + + // Mirrors AddressBlock::systemReservedAddresses() as of this migration: network + broadcast + // for IPv4 blocks wider than a point-to-point /31, the subnet-router anycast for IPv6, and + // the configured gateway. Spelled out in SQL rather than driven through the model so a later + // change to that method can't retroactively rewrite what this backfill did. + // host() normalizes both sides to a bare address, since inet equality also compares masklen. + DB::statement(<<<'SQL' + UPDATE addresses a + SET state_reason = 'system' + FROM address_blocks b + WHERE a.address_block_id = b.id + AND a.state = 'reserved' + AND ( + (b.version = 'ipv6' AND host(a.ip) = host(b.base_ip)) + OR ( + b.version = 'ipv4' + AND b.prefix_length_from <= 30 + AND ( + host(a.ip) = host(b.base_ip) + OR host(a.ip) = host(broadcast(set_masklen(b.base_ip, b.prefix_length_from))) + ) + ) + OR (b.gateway IS NOT NULL AND host(a.ip) = host(b.gateway)) + ) + SQL); + + // Everything else already reserved was put there by an operator. + DB::table('addresses') + ->where('state', 'reserved') + ->whereNull('state_reason') + ->update(['state_reason' => 'admin']); + } + + public function down(): void + { + Schema::table('addresses', function (Blueprint $table) { + $table->dropColumn('state_reason'); + }); + } +}; diff --git a/database/migrations/2026_07_25_000000_create_vlans_table.php b/database/migrations/2026_07_25_000000_create_vlans_table.php new file mode 100644 index 00000000000..a63f2fd36ca --- /dev/null +++ b/database/migrations/2026_07_25_000000_create_vlans_table.php @@ -0,0 +1,90 @@ +id(); + $table->foreignId('network_interface_id') + ->constrained('network_interfaces') + ->cascadeOnDelete(); + $table->unsignedSmallInteger('tag'); + $table->string('name')->nullable(); + $table->string('description')->nullable(); + + // A tag is only meaningful within one bridge, so uniqueness is + // scoped to the interface rather than global. + $table->unique(['network_interface_id', 'tag']); + }); + + $this->backfill(); + } + + /** + * Before this table existed a VLAN had no record — it was inferred from the + * tags in use. Declare one row for every tag already resolvable today so + * that existing trunks don't render as empty on first load: + * + * - the bridge's own default tag, and + * - every distinct tag carried by a server sitting on that bridge. + * + * Only VLAN-aware interfaces are considered, matching the resolution in + * ServerNetworkService: a non-aware bridge forces a null tag, so any tag + * lingering on one is inert and must not be promoted into a declaration. + */ + private function backfill(): void + { + $rows = DB::table('network_interfaces') + ->where('is_vlan_aware', true) + ->whereNotNull('vlan_tag') + ->select('id as network_interface_id', 'vlan_tag as tag') + ->union( + DB::table('servers') + ->join( + 'network_interfaces', + 'servers.network_interface_id', + '=', + 'network_interfaces.id', + ) + ->where('network_interfaces.is_vlan_aware', true) + ->whereNotNull('servers.vlan_tag') + ->select( + 'network_interfaces.id as network_interface_id', + 'servers.vlan_tag as tag', + ) + ->distinct(), + ) + ->get(); + + if ($rows->isEmpty()) { + return; + } + + // `union` de-duplicates across the two halves, but a bridge default that + // a server also carries explicitly can still arrive twice from the same + // half on some drivers — key the insert to be certain. + DB::table('vlans')->insert( + $rows + ->keyBy(fn ($row) => "{$row->network_interface_id}:{$row->tag}") + ->map(fn ($row) => [ + 'network_interface_id' => $row->network_interface_id, + 'tag' => $row->tag, + 'name' => null, + 'description' => null, + ]) + ->values() + ->all(), + ); + } + + public function down(): void + { + Schema::dropIfExists('vlans'); + } +}; diff --git a/database/migrations/2026_07_25_000000_requalify_system_reservations_on_delegating_blocks.php b/database/migrations/2026_07_25_000000_requalify_system_reservations_on_delegating_blocks.php new file mode 100644 index 00000000000..fac8d463279 --- /dev/null +++ b/database/migrations/2026_07_25_000000_requalify_system_reservations_on_delegating_blocks.php @@ -0,0 +1,70 @@ + {$gatewayUnit}) + SQL); + + // 2. Reserve the gateway's unit where it was missed. Only rows that are currently available: + // one already assigned to a server predates this fix and is the operator's to resolve — + // silently yanking a VM's address here would be a worse failure than the original bug. + DB::statement(<<whereRaw("version <> ('ipv' || family(base_ip)::text)") + ->pluck('id'); + + if ($mismatched->isNotEmpty()) { + throw new RuntimeException( + 'Cannot derive address_blocks.version from base_ip: block(s) '.$mismatched->implode(', '). + ' declare a version that disagrees with their base IP. Correct the base IP (or delete the block) and re-run.' + ); + } + + // Postgres has no ALTER COLUMN ... ADD GENERATED for stored columns, so the column has to be + // dropped and re-added. Values are fully reproducible from base_ip, so nothing is lost. + DB::statement('ALTER TABLE address_blocks DROP COLUMN version'); + DB::statement(<<<'SQL' + ALTER TABLE address_blocks + ADD COLUMN version VARCHAR(4) + GENERATED ALWAYS AS ((CASE WHEN family(base_ip) = 4 THEN 'ipv4' ELSE 'ipv6' END)::varchar(4)) STORED + SQL); + } + + public function down(): void + { + DB::statement('ALTER TABLE address_blocks DROP COLUMN version'); + DB::statement('ALTER TABLE address_blocks ADD COLUMN version VARCHAR(255)'); + DB::statement("UPDATE address_blocks SET version = 'ipv' || family(base_ip)::text"); + DB::statement('ALTER TABLE address_blocks ALTER COLUMN version SET NOT NULL'); + } +}; diff --git a/database/migrations/2026_07_31_000001_split_server_suspension_from_lifecycle.php b/database/migrations/2026_07_31_000001_split_server_suspension_from_lifecycle.php new file mode 100644 index 00000000000..c92e1ba0d7b --- /dev/null +++ b/database/migrations/2026_07_31_000001_split_server_suspension_from_lifecycle.php @@ -0,0 +1,63 @@ +timestamp('suspended_at')->nullable()->after('status'); + }); + + // The old value carried no suspension time, so `now` is the only honest answer -- these + // rows were suspended at some unknown point before this migration ran. The lifecycle + // stage they were at before suspension is not recoverable (the old column overwrote it), + // and `ready` is the stage a suspendable server was overwhelmingly likely to be in. + DB::table('servers') + ->where('status', 'suspended') + ->update([ + 'suspended_at' => now(), + 'status' => 'ready', + ]); + + // Postgres carries the NOT NULL and the `ready` default across a rename, so the column's + // shape is unchanged -- only its name and the set of values it can hold. + Schema::table('servers', function (Blueprint $table) { + $table->renameColumn('status', 'lifecycle'); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->renameColumn('lifecycle', 'status'); + }); + + // Folding suspension back in is lossy in the same way it always was: the lifecycle stage + // of a suspended server is overwritten, because the old schema had nowhere to keep it. + DB::table('servers') + ->whereNotNull('suspended_at') + ->update(['status' => 'suspended']); + + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('suspended_at'); + }); + } +}; diff --git a/database/migrations/2026_08_02_000000_add_panel_url_override_to_anchors.php b/database/migrations/2026_08_02_000000_add_panel_url_override_to_anchors.php new file mode 100644 index 00000000000..27922c16567 --- /dev/null +++ b/database/migrations/2026_08_02_000000_add_panel_url_override_to_anchors.php @@ -0,0 +1,29 @@ +string('panel_url_override', 2048)->nullable()->after('public_url'); + }); + } + + public function down(): void + { + Schema::table('anchors', function (Blueprint $table) { + $table->dropColumn('panel_url_override'); + }); + } +}; diff --git a/database/migrations/2026_08_17_000000_create_server_presets_table.php b/database/migrations/2026_08_17_000000_create_server_presets_table.php new file mode 100644 index 00000000000..b6c88ee942c --- /dev/null +++ b/database/migrations/2026_08_17_000000_create_server_presets_table.php @@ -0,0 +1,41 @@ +id(); + $table->uuid()->unique(); + // Unique so the create page's picker never shows two entries an + // admin cannot tell apart. + $table->string('name')->unique(); + $table->string('description')->nullable(); + + /* + * The saved half of the create form, as JSON rather than a column + * per field. A preset is deliberately *partial* — every key is + * optional, and one that is absent leaves the form's own default + * alone — so a column set would be a wall of nullables that has to + * be migrated again every time the create form grows a field. + * + * Values are stored in the units the form itself uses (MiB for + * memory/disk, GiB per extra disk, MB/s for the speed cap), so + * applying a preset is a plain field-set; the byte conversions stay + * where they already live, at submit time. + */ + $table->json('settings'); + + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('server_presets'); + } +}; diff --git a/database/migrations/2026_08_17_000001_add_discovered_columns_to_storages_table.php b/database/migrations/2026_08_17_000001_add_discovered_columns_to_storages_table.php new file mode 100644 index 00000000000..b9449e1bf1e --- /dev/null +++ b/database/migrations/2026_08_17_000001_add_discovered_columns_to_storages_table.php @@ -0,0 +1,59 @@ +string('pve_type')->nullable()->after('name'); + // PVE's own `shared` flag -- the authority `is_shareable` only guesses at. + $table->boolean('pve_shared')->nullable()->after('pve_type'); + // PVE's comma-separated content list, e.g. `images,rootdir` or `backup`. + $table->string('pve_content')->nullable()->after('pve_shared'); + + // Capacity as last reported. Nullable rather than zero-defaulted: a + // store Convoy has never reached is not a store with no space, and + // zero would be indistinguishable from a full one. + $table->unsignedBigInteger('discovered_total')->nullable()->after('pve_content'); + $table->unsignedBigInteger('discovered_used')->nullable()->after('discovered_total'); + $table->timestamp('discovered_at')->nullable()->after('discovered_used'); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + $table->dropColumn([ + 'pve_type', + 'pve_shared', + 'pve_content', + 'discovered_total', + 'discovered_used', + 'discovered_at', + ]); + }); + } +}; diff --git a/database/migrations/2026_08_17_000002_add_cluster_name_to_nodes_table.php b/database/migrations/2026_08_17_000002_add_cluster_name_to_nodes_table.php new file mode 100644 index 00000000000..507e68e0d9c --- /dev/null +++ b/database/migrations/2026_08_17_000002_add_cluster_name_to_nodes_table.php @@ -0,0 +1,35 @@ +string('cluster_name')->nullable()->after('name'); + }); + } + + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn('cluster_name'); + }); + } +}; diff --git a/database/migrations/2026_08_17_000003_drop_is_shareable_from_storages_table.php b/database/migrations/2026_08_17_000003_drop_is_shareable_from_storages_table.php new file mode 100644 index 00000000000..248240d2670 --- /dev/null +++ b/database/migrations/2026_08_17_000003_drop_is_shareable_from_storages_table.php @@ -0,0 +1,38 @@ +dropColumn('is_shareable'); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + $table->boolean('is_shareable')->default(false); + }); + } +}; diff --git a/database/migrations/2026_08_19_000000_create_audit_logs_table.php b/database/migrations/2026_08_19_000000_create_audit_logs_table.php new file mode 100644 index 00000000000..52e870e62da --- /dev/null +++ b/database/migrations/2026_08_19_000000_create_audit_logs_table.php @@ -0,0 +1,105 @@ +id(); + + // Groups the several rows a single user action can produce (a bulk delete, say). + $table->uuid('batch')->nullable(); + + // An App\Enums\Audit\AuditEvent value. + $table->string('event'); + + // User, or SystemActor for panel-wide application tokens. Null means the action could + // not be attributed — rare enough that it should be treated as suspicious. + // Columns declared by hand rather than via nullableNumericMorphs(): that helper adds its + // own (type, id) index, which would be a strict prefix of the (type, id, created_at) + // composite below and therefore pure write overhead on an append-only table. + $table->string('actor_type')->nullable(); + $table->unsignedBigInteger('actor_id')->nullable(); + + // The actor's display name, copied at write time. No model in this panel soft-deletes, + // so the morph above resolves to null the moment the user is removed — and an audit + // log that forgets who acted the instant you delete their account is not an audit log. + // Denormalised deliberately: it is a snapshot of who they were then, not a live join. + $table->string('actor_label')->nullable(); + + // Set when the action arrived over the API, so a leaked key's blast radius is visible. + // nullOnDelete, not cascade: revoking a token must not erase what it did. + $table->foreignId('api_token_id')->nullable() + ->constrained('personal_access_tokens')->nullOnDelete(); + + // Whatever was acted on. Nullable because a few events (panel settings) have no subject. + $table->string('subject_type')->nullable(); + $table->unsignedBigInteger('subject_id')->nullable(); + + // 45 characters is the longest possible IPv6 representation. + $table->string('ip', 45)->nullable(); + $table->string('user_agent', 500)->nullable(); + + $table->json('properties'); + + // Append-only, so `created_at` alone. The predecessor's bespoke `timestamp` column is + // exactly what drifted from the model and broke the nightly prune; stick to the + // Laravel convention this time. + $table->timestamp('created_at')->nullable(); + + // The client activity feed and the per-user admin view are both "newest first, for one + // morph target", which is what these composites serve. They also cover plain + // (type, id) lookups by prefix, so no separate morph index is needed. + $table->index(['subject_type', 'subject_id', 'created_at']); + $table->index(['actor_type', 'actor_id', 'created_at']); + $table->index('event'); + $table->index('batch'); + + // Drives the pruner's range scan. + $table->index('created_at'); + }); + } + + public function down(): void + { + Schema::dropIfExists('audit_logs'); + + // Recreated at their final 2022 shape so a rollback lands somewhere coherent, even though + // nothing reads them any more. + Schema::create('activity_logs', function (Blueprint $table) { + $table->id(); + $table->uuid('batch')->nullable(); + $table->string('event')->index(); + $table->string('ip'); + $table->text('description')->nullable(); + $table->nullableNumericMorphs('actor'); + $table->json('properties'); + $table->timestamp('timestamp')->useCurrent(); + }); + + Schema::create('activity_log_subjects', function (Blueprint $table) { + $table->id(); + $table->foreignId('activity_log_id')->constrained()->cascadeOnDelete(); + $table->numericMorphs('subject'); + }); + } +}; diff --git a/database/migrations/2026_08_20_000001_create_clusters_table.php b/database/migrations/2026_08_20_000001_create_clusters_table.php new file mode 100644 index 00000000000..e747540936e --- /dev/null +++ b/database/migrations/2026_08_20_000001_create_clusters_table.php @@ -0,0 +1,52 @@ +id(); + $table->string('fingerprint')->nullable()->unique(); + // Display label from /cluster/status; carries no identity. + $table->string('name')->nullable(); + $table->json('member_names')->nullable(); + $table->timestamp('flagged_at')->nullable(); + $table->string('flag_reason')->nullable(); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('clusters'); + } +}; diff --git a/database/migrations/2026_08_20_000002_add_cluster_id_to_nodes_table.php b/database/migrations/2026_08_20_000002_add_cluster_id_to_nodes_table.php new file mode 100644 index 00000000000..dd21950f7db --- /dev/null +++ b/database/migrations/2026_08_20_000002_add_cluster_id_to_nodes_table.php @@ -0,0 +1,74 @@ +foreignId('cluster_id') + ->nullable() + ->after('name') + ->constrained('clusters') + ->nullOnDelete(); + }); + + $now = now(); + + foreach (DB::table('nodes')->get(['id', 'cluster_name']) as $node) { + $clusterId = DB::table('clusters')->insertGetId([ + 'fingerprint' => null, + 'name' => $node->cluster_name, + 'member_names' => null, + 'created_at' => $now, + 'updated_at' => $now, + ]); + + DB::table('nodes')->where('id', $node->id)->update(['cluster_id' => $clusterId]); + } + + Schema::table('nodes', function (Blueprint $table) { + $table->dropColumn('cluster_name'); + }); + } + + public function down(): void + { + Schema::table('nodes', function (Blueprint $table) { + $table->string('cluster_name')->nullable()->after('name'); + }); + + // Real clusters get their label back; a singleton's label was only + // ever a leftover of the forward migration, but restoring it loses + // nothing either way. + foreach (DB::table('clusters')->whereNotNull('name')->get(['id', 'name']) as $cluster) { + DB::table('nodes')->where('cluster_id', $cluster->id)->update(['cluster_name' => $cluster->name]); + } + + Schema::table('nodes', function (Blueprint $table) { + $table->dropConstrainedForeignId('cluster_id'); + }); + } +}; diff --git a/database/migrations/2026_08_20_000003_add_cluster_id_to_storages_table.php b/database/migrations/2026_08_20_000003_add_cluster_id_to_storages_table.php new file mode 100644 index 00000000000..83bb6da948c --- /dev/null +++ b/database/migrations/2026_08_20_000003_add_cluster_id_to_storages_table.php @@ -0,0 +1,108 @@ +foreignId('cluster_id') + ->nullable() + ->after('id') + ->constrained('clusters') + ->nullOnDelete(); + }); + + $links = DB::table('storage_to_node') + ->join('nodes', 'nodes.id', '=', 'storage_to_node.node_id') + ->orderBy('storage_to_node.node_id') + ->get(['storage_to_node.storage_id', 'nodes.cluster_id']); + + foreach ($links->groupBy('storage_id') as $storageId => $rows) { + DB::table('storages') + ->where('id', $storageId) + ->update(['cluster_id' => $rows->first()->cluster_id]); + } + + $duplicates = DB::table('storages') + ->select('cluster_id', 'name', DB::raw('min(id) as keeper_id')) + ->whereNotNull('cluster_id') + ->groupBy('cluster_id', 'name') + ->havingRaw('count(*) > 1') + ->get(); + + foreach ($duplicates as $duplicate) { + $loserIds = DB::table('storages') + ->where('cluster_id', $duplicate->cluster_id) + ->where('name', $duplicate->name) + ->where('id', '!=', $duplicate->keeper_id) + ->pluck('id'); + + foreach (self::REFERENCING_TABLES as $table) { + DB::table($table) + ->whereIn('storage_id', $loserIds) + ->update(['storage_id' => $duplicate->keeper_id]); + } + + // Links move one at a time so a pair the keeper already has is + // dropped rather than duplicated. + foreach (DB::table('storage_to_node')->whereIn('storage_id', $loserIds)->get() as $link) { + $keeperHasPair = DB::table('storage_to_node') + ->where('storage_id', $duplicate->keeper_id) + ->where('node_id', $link->node_id) + ->exists(); + + $query = DB::table('storage_to_node') + ->where('storage_id', $link->storage_id) + ->where('node_id', $link->node_id); + + $keeperHasPair + ? $query->delete() + : $query->update(['storage_id' => $duplicate->keeper_id]); + } + + DB::table('storages')->whereIn('id', $loserIds)->delete(); + } + + Schema::table('storages', function (Blueprint $table) { + $table->unique(['cluster_id', 'name']); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + $table->dropUnique(['cluster_id', 'name']); + $table->dropConstrainedForeignId('cluster_id'); + }); + } +}; diff --git a/database/migrations/2026_08_20_000004_move_discovered_capacity_to_storage_to_node.php b/database/migrations/2026_08_20_000004_move_discovered_capacity_to_storage_to_node.php new file mode 100644 index 00000000000..6d9df02e75b --- /dev/null +++ b/database/migrations/2026_08_20_000004_move_discovered_capacity_to_storage_to_node.php @@ -0,0 +1,110 @@ +unsignedBigInteger('discovered_total')->nullable(); + $table->unsignedBigInteger('discovered_used')->nullable(); + $table->timestamp('discovered_at')->nullable(); + }); + + $observed = DB::table('storages') + ->whereNotNull('discovered_at') + ->get(['id', 'discovered_total', 'discovered_used', 'discovered_at']); + + foreach ($observed as $storage) { + DB::table('storage_to_node') + ->where('storage_id', $storage->id) + ->update([ + 'discovered_total' => $storage->discovered_total, + 'discovered_used' => $storage->discovered_used, + 'discovered_at' => $storage->discovered_at, + ]); + } + + // Collapse exact duplicate pairs (grouped in PHP: the table has no id + // column to key a portable SQL dedupe on). + $pairs = DB::table('storage_to_node')->get()->groupBy( + fn ($link) => "{$link->storage_id}:{$link->node_id}", + ); + + foreach ($pairs as $rows) { + if ($rows->count() < 2) { + continue; + } + + $keeper = clone $rows->sortByDesc(fn ($link) => $link->discovered_at ?? '')->first(); + + DB::table('storage_to_node') + ->where('storage_id', $keeper->storage_id) + ->where('node_id', $keeper->node_id) + ->delete(); + + DB::table('storage_to_node')->insert((array) $keeper); + } + + Schema::table('storage_to_node', function (Blueprint $table) { + $table->unique(['storage_id', 'node_id']); + }); + + Schema::table('storages', function (Blueprint $table) { + $table->dropColumn(['discovered_total', 'discovered_used', 'discovered_at']); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + $table->unsignedBigInteger('discovered_total')->nullable()->after('pve_content'); + $table->unsignedBigInteger('discovered_used')->nullable()->after('discovered_total'); + $table->timestamp('discovered_at')->nullable()->after('discovered_used'); + }); + + // Freshest link wins: for a shared pool any reading is the pool's, and + // for a local one it is at least a real observation rather than none. + $links = DB::table('storage_to_node') + ->whereNotNull('discovered_at') + ->orderBy('discovered_at') + ->get(); + + foreach ($links as $link) { + DB::table('storages')->where('id', $link->storage_id)->update([ + 'discovered_total' => $link->discovered_total, + 'discovered_used' => $link->discovered_used, + 'discovered_at' => $link->discovered_at, + ]); + } + + Schema::table('storage_to_node', function (Blueprint $table) { + $table->dropUnique(['storage_id', 'node_id']); + $table->dropColumn(['discovered_total', 'discovered_used', 'discovered_at']); + }); + } +}; diff --git a/database/migrations/2026_08_20_000005_add_placement_columns_to_servers_table.php b/database/migrations/2026_08_20_000005_add_placement_columns_to_servers_table.php new file mode 100644 index 00000000000..ec16ace599a --- /dev/null +++ b/database/migrations/2026_08_20_000005_add_placement_columns_to_servers_table.php @@ -0,0 +1,42 @@ +char('smbios_uuid', 36)->nullable()->after('uuid_short'); + $table->timestamp('flagged_at')->nullable()->after('suspended_at'); + $table->string('flag_reason')->nullable()->after('flagged_at'); + }); + } + + public function down(): void + { + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn(['smbios_uuid', 'flagged_at', 'flag_reason']); + }); + } +}; diff --git a/database/migrations/2026_08_20_000006_create_anchor_enrollment_keys_table.php b/database/migrations/2026_08_20_000006_create_anchor_enrollment_keys_table.php new file mode 100644 index 00000000000..f741c3a5161 --- /dev/null +++ b/database/migrations/2026_08_20_000006_create_anchor_enrollment_keys_table.php @@ -0,0 +1,76 @@ +id(); + $table->uuid('uuid')->unique(); + $table->string('name'); + $table->string('token_hash', 64)->unique(); + + /* + * Which mode a presenting installation may claim, or null for + * either. A key cut for a rack of Proxmox hosts has no business + * standing up a relay. + */ + $table->string('mode')->nullable(); + + /* + * Null max_uses means unlimited -- deliberately expressible, and + * deliberately not the default the API hands out. A reusable key + * baked into a machine image is the whole point of this feature for + * a fleet; it is also the shape most worth being explicit about. + */ + $table->unsignedInteger('max_uses')->nullable(); + $table->unsignedInteger('uses')->default(0); + + $table->timestamp('expires_at')->nullable(); + $table->timestamp('revoked_at')->nullable(); + $table->timestamp('last_used_at')->nullable(); + + /* + * Who let these machines in. Nulled rather than cascaded when that + * admin is deleted: the key outlives the person, and the audit log + * keeps the name via `actor_label` regardless. + */ + $table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete(); + + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('anchor_enrollment_keys'); + } +}; diff --git a/database/migrations/2026_08_20_000007_add_self_registration_to_anchors.php b/database/migrations/2026_08_20_000007_add_self_registration_to_anchors.php new file mode 100644 index 00000000000..80dc0bb676f --- /dev/null +++ b/database/migrations/2026_08_20_000007_add_self_registration_to_anchors.php @@ -0,0 +1,78 @@ +foreignId('enrollment_key_id') + ->nullable() + ->after('relay_id') + ->constrained('anchor_enrollment_keys') + ->nullOnDelete(); + + $table->json('reported_facts')->nullable()->after('capabilities'); + $table->timestamp('approved_at')->nullable()->after('enrolled_at'); + }); + + DB::table('anchors')->whereNull('approved_at')->update([ + 'approved_at' => DB::raw('created_at'), + ]); + + Schema::table('anchors', function (Blueprint $table) { + $table->string('public_url')->nullable()->change(); + }); + } + + public function down(): void + { + // Restore the NOT NULL contract before re-imposing it. Any row still + // holding null never completed approval, so there is no correct address + // to put back -- an empty string is the honest placeholder for a value + // that was never established. + DB::table('anchors')->whereNull('public_url')->update(['public_url' => '']); + + Schema::table('anchors', function (Blueprint $table) { + $table->string('public_url')->nullable(false)->change(); + $table->dropColumn(['reported_facts', 'approved_at']); + $table->dropConstrainedForeignId('enrollment_key_id'); + }); + } +}; diff --git a/database/migrations/2026_08_22_000000_merge_anchors_into_nodes.php b/database/migrations/2026_08_22_000000_merge_anchors_into_nodes.php new file mode 100644 index 00000000000..10c59aa7d97 --- /dev/null +++ b/database/migrations/2026_08_22_000000_merge_anchors_into_nodes.php @@ -0,0 +1,354 @@ +id(); + $table->uuid('uuid')->unique(); + $table->string('name'); + $table->string('public_url', 2048)->nullable(); + $table->string('panel_url_override', 2048)->nullable(); + $table->text('secret'); + $table->foreignId('enrollment_key_id')->nullable() + ->constrained('anchor_enrollment_keys')->nullOnDelete(); + $table->string('enrollment_token_hash', 64)->nullable()->unique(); + $table->timestamp('enrollment_expires_at')->nullable(); + $table->timestamp('enrolled_at')->nullable(); + $table->timestamp('last_seen_at')->nullable(); + $table->string('version')->nullable(); + $table->unsignedSmallInteger('protocol_min')->nullable(); + $table->unsignedSmallInteger('protocol_max')->nullable(); + $table->json('capabilities')->nullable(); + $table->json('reported_facts')->nullable(); + $table->timestamps(); + }); + + Schema::create('anchor_enrollments', function (Blueprint $table) { + $table->id(); + $table->uuid('uuid')->unique(); + $table->string('name'); + // Which of the two tables above this becomes when it is approved. + $table->string('mode'); + $table->text('secret'); + $table->foreignId('enrollment_key_id')->nullable() + ->constrained('anchor_enrollment_keys')->nullOnDelete(); + $table->json('reported_facts')->nullable(); + $table->timestamp('enrolled_at')->nullable(); + $table->timestamp('last_seen_at')->nullable(); + $table->string('version')->nullable(); + $table->unsignedSmallInteger('protocol_min')->nullable(); + $table->unsignedSmallInteger('protocol_max')->nullable(); + $table->json('capabilities')->nullable(); + $table->timestamps(); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->uuid('agent_uuid')->nullable()->unique()->after('anchor_id'); + $table->text('agent_secret')->nullable()->after('agent_uuid'); + $table->string('agent_public_url', 2048)->nullable()->after('agent_secret'); + $table->string('agent_panel_url_override', 2048)->nullable()->after('agent_public_url'); + $table->foreignId('relay_id')->nullable()->after('agent_panel_url_override') + ->constrained('relays')->nullOnDelete(); + $table->foreignId('agent_enrollment_key_id')->nullable()->after('relay_id') + ->constrained('anchor_enrollment_keys')->nullOnDelete(); + $table->string('agent_enrollment_token_hash', 64)->nullable()->unique()->after('agent_enrollment_key_id'); + $table->timestamp('agent_enrollment_expires_at')->nullable()->after('agent_enrollment_token_hash'); + $table->timestamp('agent_enrolled_at')->nullable()->after('agent_enrollment_expires_at'); + $table->timestamp('agent_last_seen_at')->nullable()->after('agent_enrolled_at'); + $table->string('agent_version')->nullable()->after('agent_last_seen_at'); + $table->unsignedSmallInteger('agent_protocol_min')->nullable()->after('agent_version'); + $table->unsignedSmallInteger('agent_protocol_max')->nullable()->after('agent_protocol_min'); + $table->json('agent_capabilities')->nullable()->after('agent_protocol_max'); + $table->json('agent_reported_facts')->nullable()->after('agent_capabilities'); + }); + + if (Schema::hasTable('anchors')) { + $this->migrateAnchors(); + } + + Schema::table('nodes', function (Blueprint $table) { + $table->dropConstrainedForeignId('anchor_id'); + }); + + Schema::dropIfExists('anchors'); + } + + /** + * Moves each anchor to whichever of the three tables now describes it. + * + * Order matters: relays are created first so the agents that route through + * one have a row to point at. + */ + private function migrateAnchors(): void + { + /** @var array old anchors.id => new relays.id */ + $relayIds = []; + + foreach (DB::table('anchors')->where('mode', 'relay')->whereNotNull('approved_at')->get() as $relay) { + $relayIds[$relay->id] = DB::table('relays')->insertGetId([ + 'uuid' => $relay->uuid, + 'name' => $relay->name, + 'public_url' => $relay->public_url, + 'panel_url_override' => $relay->panel_url_override, + 'secret' => $relay->secret, + 'enrollment_key_id' => $relay->enrollment_key_id, + 'enrollment_token_hash' => $relay->enrollment_token_hash, + 'enrollment_expires_at' => $relay->enrollment_expires_at, + 'enrolled_at' => $relay->enrolled_at, + 'last_seen_at' => $relay->last_seen_at, + 'version' => $relay->version, + 'protocol_min' => $relay->protocol_min, + 'protocol_max' => $relay->protocol_max, + 'capabilities' => $relay->capabilities, + 'reported_facts' => $relay->reported_facts, + 'created_at' => $relay->created_at, + 'updated_at' => $relay->updated_at, + ]); + } + + // Anything never approved is still a claim, whichever mode it claimed. + foreach (DB::table('anchors')->whereNull('approved_at')->get() as $pending) { + DB::table('anchor_enrollments')->insert([ + 'uuid' => $pending->uuid, + 'name' => $pending->name, + 'mode' => $pending->mode, + 'secret' => $pending->secret, + 'enrollment_key_id' => $pending->enrollment_key_id, + 'reported_facts' => $pending->reported_facts, + 'enrolled_at' => $pending->enrolled_at, + 'last_seen_at' => $pending->last_seen_at, + 'version' => $pending->version, + 'protocol_min' => $pending->protocol_min, + 'protocol_max' => $pending->protocol_max, + 'capabilities' => $pending->capabilities, + 'created_at' => $pending->created_at, + 'updated_at' => $pending->updated_at, + ]); + } + + $agents = DB::table('anchors') + ->where('mode', 'agent') + ->whereNotNull('approved_at') + ->get() + ->keyBy('id'); + + foreach (DB::table('nodes')->whereNotNull('anchor_id')->get(['id', 'anchor_id']) as $node) { + $agent = $agents->get($node->anchor_id); + + if ($agent === null) { + continue; + } + + DB::table('nodes')->where('id', $node->id)->update([ + 'agent_uuid' => $agent->uuid, + 'agent_secret' => $agent->secret, + 'agent_public_url' => $agent->public_url, + 'agent_panel_url_override' => $agent->panel_url_override, + 'relay_id' => $agent->relay_id === null ? null : ($relayIds[$agent->relay_id] ?? null), + 'agent_enrollment_key_id' => $agent->enrollment_key_id, + 'agent_enrollment_token_hash' => $agent->enrollment_token_hash, + 'agent_enrollment_expires_at' => $agent->enrollment_expires_at, + 'agent_enrolled_at' => $agent->enrolled_at, + 'agent_last_seen_at' => $agent->last_seen_at, + 'agent_version' => $agent->version, + 'agent_protocol_min' => $agent->protocol_min, + 'agent_protocol_max' => $agent->protocol_max, + 'agent_capabilities' => $agent->capabilities, + 'agent_reported_facts' => $agent->reported_facts, + ]); + } + + /* + * An approved agent attached to no node had nothing to serve: it could + * not open a console, because the only VMs it can reach are the ones on + * its own host and no host was pointing at it. Rather than drop it, it + * goes back to being a claim, which is what it effectively was -- an + * installation nobody had finished placing. + */ + $attached = DB::table('nodes')->whereNotNull('anchor_id')->pluck('anchor_id')->all(); + + foreach ($agents->whereNotIn('id', $attached) as $orphan) { + DB::table('anchor_enrollments')->insert([ + 'uuid' => $orphan->uuid, + 'name' => $orphan->name, + 'mode' => 'agent', + 'secret' => $orphan->secret, + 'enrollment_key_id' => $orphan->enrollment_key_id, + 'reported_facts' => $orphan->reported_facts, + 'enrolled_at' => $orphan->enrolled_at, + 'last_seen_at' => $orphan->last_seen_at, + 'version' => $orphan->version, + 'protocol_min' => $orphan->protocol_min, + 'protocol_max' => $orphan->protocol_max, + 'capabilities' => $orphan->capabilities, + 'created_at' => $orphan->created_at, + 'updated_at' => $orphan->updated_at, + ]); + } + } + + public function down(): void + { + Schema::create('anchors', function (Blueprint $table) { + $table->id(); + $table->uuid('uuid')->unique(); + $table->string('name'); + $table->string('mode'); + $table->string('public_url')->nullable(); + $table->string('panel_url_override', 2048)->nullable(); + $table->text('secret'); + $table->foreignId('relay_id')->nullable()->constrained('anchors')->nullOnDelete(); + $table->foreignId('enrollment_key_id')->nullable() + ->constrained('anchor_enrollment_keys')->nullOnDelete(); + $table->string('enrollment_token_hash', 64)->nullable()->unique(); + $table->timestamp('enrollment_expires_at')->nullable(); + $table->timestamp('enrolled_at')->nullable(); + $table->timestamp('approved_at')->nullable(); + $table->timestamp('last_seen_at')->nullable(); + $table->string('version')->nullable(); + $table->unsignedSmallInteger('protocol_min')->nullable(); + $table->unsignedSmallInteger('protocol_max')->nullable(); + $table->json('capabilities')->nullable(); + $table->json('reported_facts')->nullable(); + $table->timestamps(); + }); + + Schema::table('nodes', function (Blueprint $table) { + $table->foreignId('anchor_id')->nullable()->constrained('anchors')->nullOnDelete(); + }); + + $relayIds = []; + + foreach (DB::table('relays')->get() as $relay) { + $relayIds[$relay->id] = DB::table('anchors')->insertGetId([ + 'uuid' => $relay->uuid, + 'name' => $relay->name, + 'mode' => 'relay', + 'public_url' => $relay->public_url, + 'panel_url_override' => $relay->panel_url_override, + 'secret' => $relay->secret, + 'enrollment_key_id' => $relay->enrollment_key_id, + 'enrollment_token_hash' => $relay->enrollment_token_hash, + 'enrollment_expires_at' => $relay->enrollment_expires_at, + 'enrolled_at' => $relay->enrolled_at, + 'approved_at' => $relay->created_at, + 'last_seen_at' => $relay->last_seen_at, + 'version' => $relay->version, + 'protocol_min' => $relay->protocol_min, + 'protocol_max' => $relay->protocol_max, + 'capabilities' => $relay->capabilities, + 'reported_facts' => $relay->reported_facts, + 'created_at' => $relay->created_at, + 'updated_at' => $relay->updated_at, + ]); + } + + foreach (DB::table('nodes')->whereNotNull('agent_uuid')->get() as $node) { + $anchorId = DB::table('anchors')->insertGetId([ + 'uuid' => $node->agent_uuid, + 'name' => $node->display_name, + 'mode' => 'agent', + 'public_url' => $node->agent_public_url, + 'panel_url_override' => $node->agent_panel_url_override, + 'secret' => $node->agent_secret, + 'relay_id' => $node->relay_id === null ? null : ($relayIds[$node->relay_id] ?? null), + 'enrollment_key_id' => $node->agent_enrollment_key_id, + 'enrollment_token_hash' => $node->agent_enrollment_token_hash, + 'enrollment_expires_at' => $node->agent_enrollment_expires_at, + 'enrolled_at' => $node->agent_enrolled_at, + 'approved_at' => $node->agent_enrolled_at ?? $node->created_at, + 'last_seen_at' => $node->agent_last_seen_at, + 'version' => $node->agent_version, + 'protocol_min' => $node->agent_protocol_min, + 'protocol_max' => $node->agent_protocol_max, + 'capabilities' => $node->agent_capabilities, + 'reported_facts' => $node->agent_reported_facts, + 'created_at' => $node->created_at, + 'updated_at' => $node->updated_at, + ]); + + DB::table('nodes')->where('id', $node->id)->update(['anchor_id' => $anchorId]); + } + + foreach (DB::table('anchor_enrollments')->get() as $pending) { + DB::table('anchors')->insert([ + 'uuid' => $pending->uuid, + 'name' => $pending->name, + 'mode' => $pending->mode, + 'public_url' => null, + 'secret' => $pending->secret, + 'enrollment_key_id' => $pending->enrollment_key_id, + 'enrolled_at' => $pending->enrolled_at, + 'approved_at' => null, + 'last_seen_at' => $pending->last_seen_at, + 'version' => $pending->version, + 'protocol_min' => $pending->protocol_min, + 'protocol_max' => $pending->protocol_max, + 'capabilities' => $pending->capabilities, + 'reported_facts' => $pending->reported_facts, + 'created_at' => $pending->created_at, + 'updated_at' => $pending->updated_at, + ]); + } + + Schema::table('nodes', function (Blueprint $table) { + $table->dropConstrainedForeignId('relay_id'); + $table->dropConstrainedForeignId('agent_enrollment_key_id'); + $table->dropColumn([ + 'agent_uuid', 'agent_secret', 'agent_public_url', 'agent_panel_url_override', + 'agent_enrollment_token_hash', 'agent_enrollment_expires_at', 'agent_enrolled_at', + 'agent_last_seen_at', 'agent_version', 'agent_protocol_min', 'agent_protocol_max', + 'agent_capabilities', 'agent_reported_facts', + ]); + }); + + Schema::dropIfExists('anchor_enrollments'); + Schema::dropIfExists('relays'); + } +}; diff --git a/database/migrations/2026_09_07_000000_replace_templates_with_images.php b/database/migrations/2026_09_07_000000_replace_templates_with_images.php new file mode 100644 index 00000000000..7ea68785ab6 --- /dev/null +++ b/database/migrations/2026_09_07_000000_replace_templates_with_images.php @@ -0,0 +1,153 @@ +dropForeign(['template_id']); + $table->dropColumn('template_id'); + }); + + // Left behind by the reverted registry-import work: it recorded which + // template was cached on which node, which is the exact coupling direct + // import removes. No migration on this branch creates it, so this is a + // no-op on a clean database and a tidy-up on a drifted one. + Schema::dropIfExists('template_installs'); + + Schema::dropIfExists('templates'); + Schema::dropIfExists('template_groups'); + + Schema::create('image_groups', function (Blueprint $table) { + $table->id(); + $table->uuid(); + $table->string('name'); + $table->text('description')->nullable(); + $table->string('icon')->nullable(); + $table->boolean('is_admin_only')->default(false); + }); + + Schema::create('image_definitions', function (Blueprint $table) { + $table->id(); + $table->uuid(); + $table->foreignId('image_group_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->text('description')->nullable(); + $table->boolean('is_admin_only')->default(false); + + // Proxmox's own ostype. Every cloud-init decision branches on it, so + // it is a column rather than a key inside `hardware`. + $table->string('ostype'); + + // The rest of the qm config, stored verbatim as cofoundry captured it + // (by denylist, so keys PVE adds later survive a round trip). Columns + // here would drop anything the panel did not know about at write time. + $table->json('hardware')->default('{}'); + + // The floor a plan must clear. Cores and memory only -- an imported + // disk's size floor comes from the version, since it can change + // between builds. + $table->unsignedInteger('minimum_cores')->nullable(); + $table->unsignedBigInteger('minimum_memory')->nullable(); + + $table->timestamps(); + + $table->unique(['image_group_id', 'name']); + }); + + Schema::create('image_versions', function (Blueprint $table) { + $table->id(); + $table->uuid(); + $table->foreignId('image_definition_id')->constrained()->cascadeOnDelete(); + + // major.minor.patch, ordered by the integer triple rather than the + // string, so 1.10.0 sorts above 1.9.0. + $table->string('version'); + $table->unsignedInteger('version_major')->default(0); + $table->unsignedInteger('version_minor')->default(0); + $table->unsignedInteger('version_patch')->default(0); + + // [{slot, role, url|path, sha256, size, virtual_size, format}] + $table->json('disks'); + + // Sum of the disks' on-disk sizes, for display and transfer estimates. + $table->unsignedBigInteger('size')->default(0); + + // A version stays readable after it is retired, because servers built + // from it still point here. + $table->boolean('is_active')->default(true); + + $table->timestamps(); + + $table->unique(['image_definition_id', 'version']); + }); + + Schema::table('deployments', function (Blueprint $table) { + // Both: the definition is what an operator chose, the version is what + // they actually got. Nulled rather than cascaded on delete so a + // deployment's history survives an image being removed. + $table->foreignId('image_definition_id')->nullable()->after('server_id')->constrained()->nullOnDelete(); + $table->foreignId('image_version_id')->nullable()->after('image_definition_id')->constrained()->nullOnDelete(); + }); + } + + public function down(): void + { + Schema::table('deployments', function (Blueprint $table) { + $table->dropConstrainedForeignId('image_version_id'); + $table->dropConstrainedForeignId('image_definition_id'); + }); + + Schema::dropIfExists('image_versions'); + Schema::dropIfExists('image_definitions'); + Schema::dropIfExists('image_groups'); + + Schema::create('template_groups', function (Blueprint $table) { + $table->id(); + $table->uuid(); + $table->string('name'); + $table->text('description')->nullable(); + $table->string('icon')->nullable(); + $table->boolean('is_admin_only')->default(false); + }); + + Schema::create('templates', function (Blueprint $table) { + $table->id(); + $table->uuid(); + $table->foreignId('template_group_id')->constrained()->cascadeOnDelete(); + $table->string('name'); + $table->text('description')->nullable(); + $table->unsignedBigInteger('vmid'); + $table->boolean('is_admin_only')->default(false); + }); + + Schema::table('deployments', function (Blueprint $table) { + $table->foreignId('template_id')->nullable()->after('server_id')->constrained()->cascadeOnDelete(); + }); + } +}; diff --git a/database/migrations/2026_09_07_000001_add_import_content_to_storages_table.php b/database/migrations/2026_09_07_000001_add_import_content_to_storages_table.php new file mode 100644 index 00000000000..e0e6aedce29 --- /dev/null +++ b/database/migrations/2026_09_07_000001_add_import_content_to_storages_table.php @@ -0,0 +1,32 @@ +boolean('stores_import')->default(false)->after('stores_iso'); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + $table->dropColumn('stores_import'); + }); + } +}; diff --git a/database/migrations/2026_09_07_000002_move_isos_into_the_panel_library.php b/database/migrations/2026_09_07_000002_move_isos_into_the_panel_library.php new file mode 100644 index 00000000000..862751cf0ab --- /dev/null +++ b/database/migrations/2026_09_07_000002_move_isos_into_the_panel_library.php @@ -0,0 +1,59 @@ +delete(); + + Schema::table('iso_library', function (Blueprint $table) { + $table->dropConstrainedForeignId('storage_id'); + $table->dropColumn(['is_successful', 'completed_at']); + + // Exactly one is set. Both answer the same question -- what URL + // returns these bytes -- so a node never learns which it was given. + $table->string('url')->nullable()->after('name'); + $table->string('path')->nullable()->after('url'); + + // Content addressing is what lets a node prove it fetched the right + // file from a source the panel does not have to trust, and what + // makes "do I already have this?" answerable by name alone. + $table->string('sha256', 64)->nullable()->after('path'); + }); + } + + public function down(): void + { + DB::table('iso_library')->delete(); + + Schema::table('iso_library', function (Blueprint $table) { + $table->dropColumn(['url', 'path', 'sha256']); + $table->foreignId('storage_id')->constrained('storages')->cascadeOnDelete(); + $table->boolean('is_successful')->default(false); + $table->timestamp('completed_at')->nullable(); + }); + } +}; diff --git a/database/migrations/2026_09_07_000003_derive_storage_content_flags.php b/database/migrations/2026_09_07_000003_derive_storage_content_flags.php new file mode 100644 index 00000000000..311803570c0 --- /dev/null +++ b/database/migrations/2026_09_07_000003_derive_storage_content_flags.php @@ -0,0 +1,72 @@ + 'images', + 'stores_lxc' => 'rootdir', + 'stores_lxc_templates' => 'vztmpl', + 'stores_backups' => 'backup', + 'stores_iso' => 'iso', + 'stores_snippets' => 'snippets', + 'stores_import' => 'import', + ]; + + public function up(): void + { + // Backfill first: a row registered by hand may carry flags an operator + // set before discovery ever ran, and dropping the columns without + // reading them would lose that. + foreach (DB::table('storages')->whereNull('pve_content')->get() as $storage) { + $content = collect(self::FLAGS) + ->filter(fn (string $token, string $column) => (bool) ($storage->{$column} ?? false)) + ->values() + ->implode(','); + + if ($content !== '') { + DB::table('storages')->where('id', $storage->id)->update(['pve_content' => $content]); + } + } + + Schema::table('storages', function (Blueprint $table) { + $table->dropColumn(array_keys(self::FLAGS)); + }); + } + + public function down(): void + { + Schema::table('storages', function (Blueprint $table) { + foreach (array_keys(self::FLAGS) as $column) { + $table->boolean($column)->default(false); + } + }); + + foreach (self::FLAGS as $column => $token) { + DB::table('storages')->whereRaw( + "concat(',', coalesce(pve_content, ''), ',') like ?", + ['%,'.$token.',%'], + )->update([$column => true]); + } + } +}; diff --git a/database/migrations/2026_09_07_000004_add_avatar_path_to_users_table.php b/database/migrations/2026_09_07_000004_add_avatar_path_to_users_table.php new file mode 100644 index 00000000000..453ac91ed15 --- /dev/null +++ b/database/migrations/2026_09_07_000004_add_avatar_path_to_users_table.php @@ -0,0 +1,24 @@ +string('avatar_path')->nullable()->after('email'); + }); + } + + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('avatar_path'); + }); + } +}; diff --git a/database/migrations/2026_09_07_000005_name_image_version_size_in_bytes.php b/database/migrations/2026_09_07_000005_name_image_version_size_in_bytes.php new file mode 100644 index 00000000000..a885bd2f7e0 --- /dev/null +++ b/database/migrations/2026_09_07_000005_name_image_version_size_in_bytes.php @@ -0,0 +1,35 @@ +renameColumn('size', 'size_bytes'); + }); + } + + public function down(): void + { + Schema::table('image_versions', function (Blueprint $table) { + $table->renameColumn('size_bytes', 'size'); + }); + } +}; diff --git a/database/migrations/2026_09_07_000006_image_version_size_follows_the_cast.php b/database/migrations/2026_09_07_000006_image_version_size_follows_the_cast.php new file mode 100644 index 00000000000..721bad76600 --- /dev/null +++ b/database/migrations/2026_09_07_000006_image_version_size_follows_the_cast.php @@ -0,0 +1,51 @@ +renameColumn('size_bytes', 'size'); + }); + + // The column held bytes; the cast reads it as mebibytes. Scale what is + // already there, or every existing version reports a size 2^20 too big. + DB::table('image_versions')->update([ + 'size' => DB::raw('floor(size / 1048576)'), + ]); + } + + public function down(): void + { + DB::table('image_versions')->update([ + 'size' => DB::raw('size * 1048576'), + ]); + + Schema::table('image_versions', function (Blueprint $table) { + $table->renameColumn('size', 'size_bytes'); + }); + } +}; diff --git a/database/migrations/2026_09_07_190000_create_user_invites_table.php b/database/migrations/2026_09_07_190000_create_user_invites_table.php new file mode 100644 index 00000000000..c3e6474d5f5 --- /dev/null +++ b/database/migrations/2026_09_07_190000_create_user_invites_table.php @@ -0,0 +1,32 @@ +id(); + + // One live invite per account, enforced here rather than in the service: re-issuing + // has to invalidate the previous link, and a unique index is what makes that true + // even when two admins press the button at the same moment. + $table->foreignId('user_id')->unique()->constrained()->cascadeOnDelete(); + + // The sha256 of the token, never the token. A leaked database should not hand out + // working sign-in links, which is the same reason Sanctum stores hashes. + $table->string('token', 64)->unique(); + + $table->timestamp('expires_at'); + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('user_invites'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 6b31dae725b..a01a6ee5507 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -11,9 +11,9 @@ class DatabaseSeeder extends Seeder */ public function run(): void { - // \Convoy\Models\User::factory(10)->create(); + // \App\Models\User::factory(10)->create(); - // \Convoy\Models\User::factory()->create([ + // \App\Models\User::factory()->create([ // 'name' => 'Test User', // 'email' => 'test@example.com', // ]); diff --git a/database/seeders/DevAnchorSeeder.php b/database/seeders/DevAnchorSeeder.php new file mode 100644 index 00000000000..9b1c65a092b --- /dev/null +++ b/database/seeders/DevAnchorSeeder.php @@ -0,0 +1,74 @@ +.` bearer token: + * + * ANCHOR_UUID = installation_id + * ANCHOR_SECRET = secret + * ANCHOR_URL = public_url (where the PANEL reaches the agent) + * + * The agent's own heartbeats will still fail — it cannot reach the panel — so + * liveness comes from AnchorLivenessService probing the agent instead. That + * means ANCHOR_URL must resolve from wherever PHP runs. + * + * Idempotent, keyed on the node's Anchor, so re-running never orphans a row. + * + * Run: php artisan db:seed --class=DevAnchorSeeder + */ +class DevAnchorSeeder extends Seeder +{ + public function run(): void + { + $uuid = env('ANCHOR_UUID'); + $secret = env('ANCHOR_SECRET'); + $url = env('ANCHOR_URL'); + + if (! $uuid || ! $secret || ! $url) { + $this->command->warn( + 'DevAnchorSeeder skipped: set ANCHOR_UUID, ANCHOR_SECRET and ANCHOR_URL ' + .'in .env to match /etc/anchor/anchor.toml on the node.' + ); + + return; + } + + $fqdn = env('PROXMOX_FQDN'); + $node = $fqdn ? Node::query()->where('fqdn', $fqdn)->first() : null; + + if ($node === null) { + $this->command->warn('DevAnchorSeeder skipped: run DevNodeSeeder first.'); + + return; + } + + // The node *is* the installation now, so this writes onto the node + // rather than creating a record to link to it. + $node->update([ + 'agent_uuid' => $uuid, + 'agent_secret' => $secret, + 'agent_public_url' => rtrim($url, '/'), + // Enrollment is what proves the panel shares a secret with this + // installation; the liveness probe will not vouch for an unenrolled + // agent, so record that we did it out of band. + 'agent_enrolled_at' => $node->agent_enrolled_at ?? now(), + ]); + + $this->command->info( + "DevAnchorSeeder: agent attached to node #{$node->id} ({$node->agent_public_url})." + ); + } +} diff --git a/database/seeders/DevNodeSeeder.php b/database/seeders/DevNodeSeeder.php new file mode 100644 index 00000000000..8bfb9092ad3 --- /dev/null +++ b/database/seeders/DevNodeSeeder.php @@ -0,0 +1,75 @@ +command->warn( + 'DevNodeSeeder skipped: set PROXMOX_FQDN, PROXMOX_TOKEN_ID and ' + .'PROXMOX_TOKEN_SECRET in .env first.' + ); + + return; + } + + if ($existing = Node::query()->where('fqdn', $fqdn)->first()) { + $this->command->info("DevNodeSeeder: node for {$fqdn} already exists (#{$existing->id})."); + + return; + } + + // Reuse a location if one exists, otherwise create one with factory defaults. + $location = Location::query()->first() ?? Location::factory()->create(); + + // `name` is the *PVE cluster node name* used verbatim in the API path + // (`/nodes/{name}/...`), NOT a friendly label — get it wrong and every + // node call fails with "hostname lookup '' failed". It defaults to + // the fqdn's first DNS label (correct for a single-host `pveX.example.com`); + // override with PROXMOX_NODE_NAME when the PVE hostname differs. + $nodeName = env('PROXMOX_NODE_NAME') ?: explode('.', $fqdn)[0]; + + // Factory supplies sane resource defaults (cpu/memory/etc.); we override + // only the connection details from the environment. + $node = Node::factory()->for($location)->create([ + 'display_name' => 'Dev Proxmox', + 'name' => $nodeName, + 'fqdn' => $fqdn, + 'port' => (int) env('PROXMOX_PORT', 8006), + 'verify_tls' => filter_var(env('PROXMOX_VERIFY_TLS', false), FILTER_VALIDATE_BOOLEAN), + 'token_id' => $tokenId, + 'token_secret' => $tokenSecret, // encrypted by the model cast on save + ]); + + $this->command->info("DevNodeSeeder: created node #{$node->id} for {$fqdn}:{$node->port}."); + } +} diff --git a/database/seeders/PgloaderHarnessSeeder.php b/database/seeders/PgloaderHarnessSeeder.php new file mode 100644 index 00000000000..6291a2b9ce5 --- /dev/null +++ b/database/seeders/PgloaderHarnessSeeder.php @@ -0,0 +1,52 @@ + Postgres conversion: tinyint(1) + * booleans, bigint (node memory), timestamps, JSON, and UUIDs. + * + * Not part of the normal seed path — DatabaseSeeder does not call it. + */ +class PgloaderHarnessSeeder extends Seeder +{ + public function run(): void + { + User::factory()->count(20)->create(); + + Location::factory()->count(5)->create()->each(function (Location $location) { + Node::factory()->for($location)->count(3)->create(); + }); + + Storage::factory()->count(12)->create(); + ISO::factory()->count(10)->create(); + AddressBlockGroup::factory()->count(6)->create(); + + // Raw rows to guarantee JSON and UUID coverage regardless of factories. + foreach (range(1, 8) as $i) { + DB::table('activity_logs')->insert([ + 'batch' => (string) Str::uuid(), + 'event' => 'harness.seed', + 'ip' => '203.0.113.'.$i, + 'properties' => json_encode([ + 'index' => $i, + 'nested' => ['flag' => $i % 2 === 0, 'label' => "row-$i"], + 'unicode' => 'café ☕ '.$i, + ]), + 'timestamp' => now(), + ]); + } + } +} diff --git a/database/seeders/ServerSeeder.php b/database/seeders/ServerSeeder.php index d62b56b879c..c85bb99c319 100644 --- a/database/seeders/ServerSeeder.php +++ b/database/seeders/ServerSeeder.php @@ -2,39 +2,68 @@ namespace Database\Seeders; -use Convoy\Models\Location; -use Convoy\Models\Node; -use Convoy\Models\Server; -use Convoy\Models\User; -use Convoy\Services\Servers\ServerCreationService; +use App\Models\Location; +use App\Models\Node; +use App\Models\Server; +use App\Models\User; +use App\Services\Servers\ServerCreationService; use Illuminate\Database\Seeder; class ServerSeeder extends Seeder { /** - * Run the database seeds. + * Seed a handful of servers. Reuses the first existing user/node/location so + * running this against a live dev database gives the account you're logged in + * as something to look at; only falls back to factories on an empty database. + * + * Override the owner (and count) from the CLI, e.g.: + * ddev exec sh -c 'SEED_SERVER_USER=you@example.com php artisan db:seed --class=ServerSeeder' + * ddev exec sh -c 'SEED_SERVER_USER=3 SEED_SERVER_COUNT=5 php artisan db:seed --class=ServerSeeder' + * SEED_SERVER_USER accepts an email or a user id. */ public function run(ServerCreationService $service): void { - $location = Location::factory()->create(); - $user = User::factory()->create(); - $node = Node::factory()->for($location)->create(); + $user = $this->resolveUser(); + $location = Location::query()->first() ?? Location::factory()->create(); + $node = Node::query()->first() ?? Node::factory()->for($location)->create(); - Server::factory()->count(10)->create(function () use ($user, $node, $service) { + $count = (int) (env('SEED_SERVER_COUNT') ?: 10); + + Server::factory()->count($count)->create(function () use ($user, $node, $service) { $uuid = $service->generateUniqueUuidCombo(); return [ 'uuid' => $uuid, 'uuid_short' => substr($uuid, 0, 8), - 'user_id' => $user, - 'node_id' => $node, + 'user_id' => $user->id, + 'node_id' => $node->id, 'cpu' => 2, 'memory' => 2048 * 1024 * 1024, 'disk' => 20 * 1024 * 1024 * 1024, - 'backup_limit' => 16, - 'snapshot_limit' => 16, - 'bandwidth_limit' => 100 * 1024 * 1024 * 1024, ]; }); } + + /** + * Resolve the owner for the seeded servers: SEED_SERVER_USER (email or id) + * when set, otherwise the first existing user, falling back to a new one. + */ + private function resolveUser(): User + { + $override = env('SEED_SERVER_USER'); + + if ($override) { + $user = str_contains((string) $override, '@') + ? User::query()->where('email', $override)->first() + : User::query()->find($override); + + if (! $user) { + throw new \RuntimeException("SEED_SERVER_USER \"{$override}\" did not match any user."); + } + + return $user; + } + + return User::query()->first() ?? User::factory()->create(); + } } diff --git a/database/seeders/TmpChainSeeder.php b/database/seeders/TmpChainSeeder.php new file mode 100644 index 00000000000..0fcafb66905 --- /dev/null +++ b/database/seeders/TmpChainSeeder.php @@ -0,0 +1,39 @@ +update(['lifecycle' => ServerLifecycle::INSTALLING]); + $deployment = $server->deployments()->latest('id')->first(); + $deployment->update(['status' => DeploymentStatus::RUNNING]); + + $step = $deployment->steps()->where('name', 'start-vm')->first(); + + $action = app(BuildServerAction::class); + $call = fn (string $m, ...$a) => (new ReflectionMethod($action, $m))->invoke($action, ...$a); + + // Deliberately no real job in between: this isolates whether the chain's + // trailing closure survives serialization through Redis and runs. + $jobs = Arr::flatten([ + $call('onStart', $deployment), + $call('onComplete', $deployment), + ]); + + Bus::chain($jobs)->catch($call('onFail', $deployment))->dispatch(); + + echo 'dispatched on connection: '.config('queue.default')."\n"; + } +} diff --git a/database/seeders/TmpInstallSeeder.php b/database/seeders/TmpInstallSeeder.php new file mode 100644 index 00000000000..d7bdee28f7e --- /dev/null +++ b/database/seeders/TmpInstallSeeder.php @@ -0,0 +1,69 @@ + 'Ubuntu'], + ['uuid' => (string) Str::uuid()], + ); + $definition = ImageDefinition::firstOrCreate( + ['name' => 'Ubuntu 24.04', 'image_group_id' => $group->id], + ['uuid' => (string) Str::uuid(), 'ostype' => 'l26'], + ); + $version = $definition->versions()->firstOrCreate( + ['version' => '1.0.0'], + [ + 'uuid' => (string) Str::uuid(), + 'disks' => [[ + 'slot' => 'scsi0', + 'role' => 'system', + 'url' => 'https://example.invalid/ubuntu-24.04.qcow2', + 'path' => null, + 'sha256' => str_repeat('a', 64), + 'size' => 600 * 1024 * 1024, + 'virtual_size' => 8 * 1024 * 1024 * 1024, + 'format' => 'qcow2', + ]], + ], + ); + + $server = Server::find(4); + $server->update(['lifecycle' => ServerLifecycle::INSTALLING]); + $server->deployments()->delete(); + + $deployment = Deployment::create([ + 'server_id' => $server->id, + 'image_definition_id' => $definition->id, + 'image_version_id' => $version->id, + 'type' => DeploymentType::INSTALL, + 'status' => DeploymentStatus::RUNNING, + 'start_on_completion' => true, + 'requested_at' => now(), + 'started_at' => now(), + ]); + + $deployment->addSteps([ + ['name' => 'import', 'status' => DeploymentStatus::COMPLETED, 'progress_mode' => ProgressMode::DETERMINATE, 'progress_total' => 100, 'progress_current' => 100, 'started_at' => now(), 'completed_at' => now()], + ['name' => 'configure', 'status' => DeploymentStatus::COMPLETED, 'progress_mode' => ProgressMode::INDETERMINATE, 'started_at' => now(), 'completed_at' => now()], + ['name' => 'update-password', 'status' => DeploymentStatus::COMPLETED, 'progress_mode' => ProgressMode::INDETERMINATE, 'started_at' => now(), 'completed_at' => now()], + ['name' => 'start-vm', 'status' => DeploymentStatus::RUNNING, 'progress_mode' => ProgressMode::INDETERMINATE, 'started_at' => now()], + ]); + + echo "server uuid: {$server->uuid}\n"; + } +} diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php new file mode 100644 index 00000000000..fac669f8887 --- /dev/null +++ b/database/seeders/UserSeeder.php @@ -0,0 +1,154 @@ +resolveUser(); + + $this->seedSshKeys($user); + $this->seedApiTokens($user, $tokens); + $this->seedServerAddresses($user); + + $this->command->info("Seeded account data for {$user->email}."); + } + + /** A few realistic public keys across algorithms. */ + private function seedSshKeys(User $user): void + { + $keys = [ + 'MacBook Pro' => 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINmtig1BvfmCSRapAUEi4iEbS/B4LTZLUJr+e4mWZ9Nb eric@macbook', + 'CI Deploy Key' => 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDvZOUERdjPy/vcYlE87nBZ7SMAZcKXeEsBzucAVmSsMsI5pgdER8qWKf66/W1Bl84tX2wUG2f2v/CbWkuoTCnuM7zqtI/NzGArS4U7cqBKlovFcnnfyn5rsKdVxhaEbUIaXKwkU5MwAyuD6OEtSwbZyYKwMl86qTtEhEqfaDq1x4Q691XT9hzWbgdUVo//3agK8xZtdK0ZlnCnzRNTtDjAA0HYLv76r7QOAst0CHfa+bmw212pkFOoaXybDGME54MRHtu24c8NKmB4DH+fmJ+oXCBEO9WGBG6GllQY2wooIf1mRqnFoi6vWDc42RL67x6XVOjR9GFTyLEdSSrZGyTB deploy@ci', + 'Bastion (ops)' => 'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNpxGav8RYv4eCf4KENGxPNF3opuoEM0et9E62kiEB+1vhkLVdK8b2QBexIB/0GejuRHB9T42GJyEj7emfFpc6Q= ops@bastion', + ]; + + foreach ($keys as $name => $publicKey) { + $user->sshKeys()->firstOrCreate( + ['name' => $name], + ['public_key' => $publicKey], + ); + } + } + + /** Personal access tokens with a spread of scopes. */ + private function seedApiTokens(User $user, CreateAccountTokenService $tokens): void + { + $seeds = [ + 'Terraform Provider' => ['servers:read', 'servers:write'], + 'Monitoring (read-only)' => ['servers:read'], + 'CI Pipeline' => ['servers:write'], + ]; + + foreach ($seeds as $name => $abilities) { + $exists = PersonalAccessToken::query() + ->where('tokenable_type', $user->getMorphClass()) + ->where('tokenable_id', $user->getKey()) + ->where('type', ApiKeyType::ACCOUNT) + ->where('name', $name) + ->exists(); + + if (! $exists) { + $tokens->handle($user, $name, $abilities); + } + } + } + + /** + * Assign a few public IPv4 addresses to the user's first server so the + * Networking → Addresses card has content. This is the only server-settings + * surface backed by the DB (IPAM); SSH keys, DNS, disks and boot order all + * read live Proxmox config, so they only populate against a reachable node. + */ + private function seedServerAddresses(User $user): void + { + $server = Server::query()->where('user_id', $user->getKey())->first(); + + if (! $server) { + $this->command->warn(' No server for this user — skipping IP addresses (run ServerSeeder first).'); + + return; + } + + if ($server->addresses()->exists()) { + return; + } + + // TEST-NET-3 (203.0.113.0/24) — a documentation range, safe for fixtures. + $block = AddressBlock::factory()->create([ + 'name' => 'Public IPv4', + 'base_ip' => '203.0.113.0', + 'gateway' => '203.0.113.1', + 'prefix_length_from' => 24, + 'prefix_length_to' => 32, + ]); + + foreach (['203.0.113.10', '203.0.113.11', '203.0.113.12'] as $ip) { + Address::factory()->create([ + 'address_block_id' => $block->getKey(), + 'server_id' => $server->getKey(), + 'ip' => $ip, + 'prefix_length' => 24, + ]); + } + } + + /** + * Resolve the target user: SEED_USER (email or id) when set, otherwise the + * first existing user, falling back to creating a demo login on an empty DB. + */ + private function resolveUser(): User + { + $override = env('SEED_USER'); + + if ($override) { + $user = str_contains((string) $override, '@') + ? User::query()->where('email', $override)->first() + : User::query()->find($override); + + if (! $user) { + throw new \RuntimeException("SEED_USER \"{$override}\" did not match any user."); + } + + return $user; + } + + $existing = User::query()->first(); + + if ($existing) { + return $existing; + } + + $demo = User::factory()->create([ + 'name' => 'Demo User', + 'email' => 'demo@convoy.test', + 'root_admin' => true, + ]); + + $this->command->info('Created demo login: demo@convoy.test / password'); + + return $demo; + } +} diff --git a/database/settings/2026_07_12_155427_create_bandwidth_settings.php b/database/settings/2026_07_12_155427_create_bandwidth_settings.php new file mode 100644 index 00000000000..4ccfdd343a5 --- /dev/null +++ b/database/settings/2026_07_12_155427_create_bandwidth_settings.php @@ -0,0 +1,20 @@ +migrator->add('bandwidth.overage_action', 'throttle'); // 'throttle' | 'disconnect' + $this->migrator->add('bandwidth.overage_rate', 1_000_000); // bytes/s (1 MB/s) + } + + public function down(): void + { + $this->migrator->delete('bandwidth.overage_rate'); + $this->migrator->delete('bandwidth.overage_action'); + } +}; diff --git a/database/settings/2026_08_02_000000_create_anchor_settings.php b/database/settings/2026_08_02_000000_create_anchor_settings.php new file mode 100644 index 00000000000..3e1667efb3b --- /dev/null +++ b/database/settings/2026_08_02_000000_create_anchor_settings.php @@ -0,0 +1,26 @@ +migrator->exists('anchor.panel_url')) { + $this->migrator->add('anchor.panel_url', ''); + } + } + + public function down(): void + { + $this->migrator->deleteIfExists('anchor.panel_url'); + } +}; diff --git a/database/settings/2026_08_19_000000_create_audit_settings.php b/database/settings/2026_08_19_000000_create_audit_settings.php new file mode 100644 index 00000000000..b9938ba567c --- /dev/null +++ b/database/settings/2026_08_19_000000_create_audit_settings.php @@ -0,0 +1,24 @@ +migrator->exists('audit.reveal_staff_identity')) { + $this->migrator->add('audit.reveal_staff_identity', false); + } + } + + public function down(): void + { + $this->migrator->deleteIfExists('audit.reveal_staff_identity'); + } +}; diff --git a/database/settings/2026_09_07_000000_create_account_settings.php b/database/settings/2026_09_07_000000_create_account_settings.php new file mode 100644 index 00000000000..b3714025356 --- /dev/null +++ b/database/settings/2026_09_07_000000_create_account_settings.php @@ -0,0 +1,33 @@ +migrator->exists($property)) { + $this->migrator->add($property, true); + } + } + } + + public function down(): void + { + $this->migrator->deleteIfExists('account.allow_name_change'); + $this->migrator->deleteIfExists('account.allow_email_change'); + $this->migrator->deleteIfExists('account.allow_password_change'); + } +}; diff --git a/database/settings/2026_09_07_120000_create_mail_settings.php b/database/settings/2026_09_07_120000_create_mail_settings.php new file mode 100644 index 00000000000..cc204100d37 --- /dev/null +++ b/database/settings/2026_09_07_120000_create_mail_settings.php @@ -0,0 +1,54 @@ + '', + 'mail.port' => 587, + 'mail.username' => '', + 'mail.encryption' => 'tls', + 'mail.from_address' => '', + 'mail.from_name' => '', + ] as $property => $default) { + if (! $this->migrator->exists($property)) { + $this->migrator->add($property, $default); + } + } + + // Encrypted, so it goes in through the migrator's encrypted path rather than as a plain + // default. Blank is still blank — there is nothing to encrypt yet — but registering it + // this way keeps the property's cast consistent from the first write. + if (! $this->migrator->exists('mail.password')) { + $this->migrator->addEncrypted('mail.password', ''); + } + } + + public function down(): void + { + foreach ([ + 'mail.host', + 'mail.port', + 'mail.username', + 'mail.password', + 'mail.encryption', + 'mail.from_address', + 'mail.from_name', + ] as $property) { + $this->migrator->deleteIfExists($property); + } + } +}; diff --git a/database/settings/2026_09_07_180000_import_mail_settings_from_environment.php b/database/settings/2026_09_07_180000_import_mail_settings_from_environment.php new file mode 100644 index 00000000000..81f2633335f --- /dev/null +++ b/database/settings/2026_09_07_180000_import_mail_settings_from_environment.php @@ -0,0 +1,110 @@ +migrator->exists('mail.host')) { + return; + } + + $imported = $this->environmentSmtp(); + + // `update()` hands the closure the stored payload, which is the only way to read a + // property through the migrator — and reading it is what decides every field below. + $wasBlank = false; + + $this->migrator->update('mail.host', function ($current) use (&$wasBlank, $imported) { + $wasBlank = ($current === '' || $current === null); + + return $wasBlank && $imported !== null ? $imported['host'] : $current; + }); + + // An operator who already filled the screen in owns it; never overwrite that. + if (! $wasBlank || $imported === null) { + return; + } + + $this->migrator->update('mail.port', fn () => $imported['port']); + $this->migrator->update('mail.username', fn () => $imported['username']); + $this->migrator->update('mail.encryption', fn () => $imported['encryption']); + $this->migrator->update('mail.from_address', fn () => $imported['from_address']); + $this->migrator->update('mail.from_name', fn () => $imported['from_name']); + $this->migrator->updateEncrypted('mail.password', fn () => $imported['password']); + } + + /** + * The environment's SMTP settings, or null when there is nothing worth importing. + * + * @return array|null + */ + private function environmentSmtp(): ?array + { + // Only smtp is importable. `log` and `array` deliver nothing, and ses/postmark/resend are + // configured out of band through credentials this screen has no fields for — importing a + // host from those would be inventing one. + if (config('mail.default') !== 'smtp') { + return null; + } + + $host = (string) config('mail.mailers.smtp.host', ''); + $port = (int) config('mail.mailers.smtp.port', 587); + + if ($host === '') { + return null; + } + + // Laravel's own fallback when neither variable is set is 127.0.0.1:2525. Importing that + // pair would turn an install that never configured mail into one that looks configured + // and silently fails, which is the single most misleading outcome available here. + if ($host === '127.0.0.1' && $port === 2525) { + return null; + } + + return [ + 'host' => $host, + 'port' => $port, + 'username' => (string) config('mail.mailers.smtp.username', ''), + 'password' => (string) config('mail.mailers.smtp.password', ''), + 'encryption' => $this->encryptionFor($port)->value, + 'from_address' => (string) config('mail.from.address', ''), + 'from_name' => (string) config('mail.from.name', ''), + ]; + } + + /** + * Laravel expresses implicit TLS as the `smtps` scheme; older installs express it as port 465 + * alone. Either is enough to mean "encrypted from the first byte". + */ + private function encryptionFor(int $port): MailEncryption + { + $scheme = (string) config('mail.mailers.smtp.scheme', ''); + + return ($scheme === 'smtps' || $port === 465) + ? MailEncryption::SSL + : MailEncryption::TLS; + } + + public function down(): void + { + // Nothing: this migration copies values into properties another migration owns. Undoing + // it would mean knowing which of them the operator has edited since, and guessing wrong + // would silently stop an install's mail. + } +}; diff --git a/database/settings/2026_09_07_200000_add_account_avatar_setting.php b/database/settings/2026_09_07_200000_add_account_avatar_setting.php new file mode 100644 index 00000000000..df791e2228c --- /dev/null +++ b/database/settings/2026_09_07_200000_add_account_avatar_setting.php @@ -0,0 +1,23 @@ +migrator->exists('account.allow_avatar_change')) { + $this->migrator->add('account.allow_avatar_change', true); + } + } + + public function down(): void + { + $this->migrator->deleteIfExists('account.allow_avatar_change'); + } +}; diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml deleted file mode 100644 index 03ab12ff621..00000000000 --- a/docker-compose.ci.yml +++ /dev/null @@ -1,41 +0,0 @@ -services: - workspace: - image: performave/convoy-workspace:latest - tty: true - volumes: - - .:/var/www/ - depends_on: - database: - condition: service_healthy - redis: - condition: service_healthy - redis: - image: redis:7.0-alpine - restart: unless-stopped - command: redis-server --save 20 1 --loglevel notice --requirepass ${REDIS_PASSWORD} - expose: - - 6379 - environment: - REDIS_PASSWORD: ${REDIS_PASSWORD} - healthcheck: - test: redis-cli -a $$REDIS_PASSWORD ping | grep PONG - interval: 5s - timeout: 5s - retries: 20 - database: - image: mysql:8.0 - restart: unless-stopped - volumes: - - ./dockerfiles/mysql/data:/var/lib/mysql/ - expose: - - 3306 - environment: - MYSQL_RANDOM_ROOT_PASSWORD: true - MYSQL_DATABASE: ${DB_DATABASE} - MYSQL_USER: ${DB_USERNAME} - MYSQL_PASSWORD: ${DB_PASSWORD} - healthcheck: - test: mysqladmin ping -u$$MYSQL_USER -p$$MYSQL_PASSWORD - interval: 5s - timeout: 5s - retries: 20 diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 4eafb091cf9..00000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,92 +0,0 @@ -services: - caddy: - build: - context: ./dockerfiles/caddy - args: - - APP_ENV=$APP_ENV - - APP_URL=$APP_URL - restart: unless-stopped - volumes: - - .:/var/www/ - - ./dockerfiles/caddy/data/config:/config - - ./dockerfiles/caddy/data/data:/data - ports: - - "80:80" - - "443:443" - depends_on: - - php - env_file: .env - php: - build: - context: ./dockerfiles/php - args: - - APP_ENV=$APP_ENV - - PHP_XDEBUG=$PHP_XDEBUG - - PHP_XDEBUG_MODE=$PHP_XDEBUG_MODE - restart: unless-stopped - volumes: - - .:/var/www/ - expose: - - 9000 - depends_on: - database: - condition: service_healthy - redis: - condition: service_healthy - env_file: .env - extra_hosts: - host.docker.internal: host-gateway - workspace: - build: - context: ./dockerfiles/workspace - args: - - PHP_XDEBUG=$PHP_XDEBUG - - PHP_XDEBUG_MODE=$PHP_XDEBUG_MODE - tty: true - ports: - - "127.0.0.1:1234:1234" - volumes: - - .:/var/www/ - extra_hosts: - host.docker.internal: host-gateway - workers: - build: - context: ./dockerfiles/workers - args: - - APP_ENV=$APP_ENV - restart: unless-stopped - volumes: - - .:/var/www/ - depends_on: - database: - condition: service_healthy - redis: - condition: service_healthy - redis: - image: redis:7.0-alpine - restart: unless-stopped - command: redis-server --save 60 1 --loglevel notice --requirepass '${REDIS_PASSWORD}' - environment: - REDIS_PASSWORD: ${REDIS_PASSWORD} - healthcheck: - test: redis-cli -a $$REDIS_PASSWORD ping | grep PONG - interval: 5s - timeout: 5s - retries: 20 - database: - image: mysql:8.0 - restart: unless-stopped - volumes: - - ./dockerfiles/mysql/data:/var/lib/mysql/ - environment: - MYSQL_RANDOM_ROOT_PASSWORD: true - MYSQL_DATABASE: ${DB_DATABASE} - MYSQL_USER: ${DB_USERNAME} - MYSQL_PASSWORD: ${DB_PASSWORD} - ports: - - "127.0.0.1:3306:3306" - healthcheck: - test: mysqladmin ping -u$$MYSQL_USER -p$$MYSQL_PASSWORD - interval: 5s - timeout: 5s - retries: 20 \ No newline at end of file diff --git a/docker/convoyctl b/docker/convoyctl new file mode 100755 index 00000000000..f4a6cc63282 --- /dev/null +++ b/docker/convoyctl @@ -0,0 +1,142 @@ +#!/usr/bin/env bash +# +# convoyctl -- day-two operations for a Convoy install. +# +# Everything here is a thin wrapper over `docker compose` in the install +# directory. That is deliberate: an operator who knows Docker can ignore this +# script entirely, and one who does not never has to learn which of the five +# containers to exec into. + +set -euo pipefail + +CONVOY_DIR="${CONVOY_DIR:-/opt/convoy}" +BACKUP_DIR="${CONVOY_BACKUP_DIR:-$CONVOY_DIR/backups}" + +readonly RED=$'\033[0;31m' GREEN=$'\033[0;32m' YELLOW=$'\033[0;33m' DIM=$'\033[2m' RESET=$'\033[0m' + +err() { printf '%s\n' "${RED}error:${RESET} $*" >&2; } +info() { printf '%s\n' "${GREEN}==>${RESET} $*"; } +warn() { printf '%s\n' "${YELLOW}warning:${RESET} $*" >&2; } + +die() { err "$@"; exit 1; } + +[[ -f "$CONVOY_DIR/compose.yml" ]] || die "no Convoy install found at $CONVOY_DIR (set CONVOY_DIR to override)." +cd "$CONVOY_DIR" + +# Read the install's own settings. Without this, `backup` would dump using the +# default credentials rather than whatever the operator actually configured, and +# fail confusingly on any install that changed them. +if [[ -f .env ]]; then + while IFS='=' read -r key value; do + [[ "$key" =~ ^(DB_USERNAME|DB_DATABASE)$ ]] || continue + # Strip surrounding quotes the way Compose does. + value="${value%\"}"; value="${value#\"}" + printf -v "$key" '%s' "$value" + done < <(grep -E '^(DB_USERNAME|DB_DATABASE)=' .env || true) +fi + +compose() { docker compose "$@"; } + +# True when the bundled Postgres container is part of this project rather than +# an external database being used. +bundled_postgres() { + compose config --services 2>/dev/null | grep -qx postgres +} + +# Prefer exec into the running web container; fall back to a throwaway container +# so `artisan` still works while the stack is down. +run_artisan() { + if [[ -n "$(compose ps -q web 2>/dev/null)" ]]; then + compose exec -T web php artisan "$@" + else + warn "web container is not running; using a temporary container." + compose run --rm --no-deps -T web php artisan "$@" + fi +} + +cmd_backup() { + bundled_postgres || die "this install uses an external database; back it up with your provider's tooling." + + mkdir -p "$BACKUP_DIR" + local stamp file + stamp="$(date -u +%Y%m%dT%H%M%SZ)" + file="$BACKUP_DIR/convoy-$stamp.sql.gz" + + info "dumping database to $file" + # --clean --if-exists so the dump can be replayed over an existing database. + compose exec -T postgres pg_dump \ + --username "${DB_USERNAME:-convoy}" \ + --dbname "${DB_DATABASE:-convoy}" \ + --clean --if-exists \ + | gzip > "$file" + + info "backup complete ($(du -h "$file" | cut -f1))" + printf '%s\n' "$file" +} + +cmd_upgrade() { + if bundled_postgres; then + info "taking a database backup first" + cmd_backup >/dev/null + else + warn "external database in use -- take your own backup before continuing." + fi + + info "pulling images" + compose pull + + # Migrations run automatically when the web container starts (AUTORUN). + info "restarting the stack" + compose up -d --remove-orphans + + info "waiting for the panel to report healthy" + local waited=0 + until [[ "$(docker inspect -f '{{.State.Health.Status}}' "$(compose ps -q web)" 2>/dev/null)" == "healthy" ]]; do + (( waited >= 180 )) && die "panel did not become healthy within 3 minutes. Check 'convoyctl logs web'." + sleep 5 + waited=$(( waited + 5 )) + done + + info "upgrade complete: $(run_artisan --version 2>/dev/null | tail -1)" +} + +usage() { + cat <<'EOF' +convoyctl -- manage a Convoy installation + + convoyctl up Start the stack + convoyctl down Stop the stack (data volumes are kept) + convoyctl restart [service] Restart everything, or one service + convoyctl ps Show container status + convoyctl logs [service] Follow logs + convoyctl upgrade Back up, pull new images, restart, verify + convoyctl backup Dump the bundled database to ./backups + convoyctl artisan Run an Artisan command + convoyctl shell [service] Open a shell (default: web) + convoyctl horizon Show queue worker status + +EOF +} + +main() { + local cmd="${1:-help}" + [[ $# -gt 0 ]] && shift + + case "$cmd" in + up) compose up -d --remove-orphans ;; + down) compose down ;; + restart) compose restart "$@" ;; + ps) compose ps ;; + logs) compose logs -f --tail=200 "$@" ;; + upgrade) cmd_upgrade ;; + backup) cmd_backup ;; + artisan) run_artisan "$@" ;; + horizon) run_artisan horizon:status ;; + # The images are Alpine-based and ship no bash. + shell) compose exec "${1:-web}" sh ;; + help|-h|--help) usage ;; + *) usage; die "unknown command: $cmd" ;; + esac +} + +main "$@" diff --git a/docker/entrypoint.d/40-convoy-preflight.sh b/docker/entrypoint.d/40-convoy-preflight.sh new file mode 100644 index 00000000000..777a9f53f0b --- /dev/null +++ b/docker/entrypoint.d/40-convoy-preflight.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# Convoy preflight. Runs in every container built from this image (web, worker, +# scheduler) before serversideup's 50-laravel-automations.sh. +# +# These scripts are sourced in a subshell by docker-php-serversideup-entrypoint, +# which aborts startup on a non-zero exit. That is deliberate here: every check +# below is a condition that would otherwise surface as an opaque 500 or a queue +# that silently processes nothing, hours after the operator walked away. + +script_name="convoy-preflight" + +fail() { + echo "🛑 ERROR ($script_name): $1" >&2 + exit 1 +} + +########################################################################## +# Storage skeleton +########################################################################## +# storage/ is a volume so logs, sessions and generated files survive a +# `docker compose pull`. A named volume inherits the image's contents on first +# use, but a bind mount to a fresh host directory arrives empty -- and Laravel +# does not create these itself, it just fails to write. +for dir in \ + app/private \ + app/public \ + framework/cache/data \ + framework/sessions \ + framework/testing \ + framework/views \ + logs +do + target="${APP_BASE_DIR:-/var/www/html}/storage/$dir" + [ -d "$target" ] && continue + + mkdir -p "$target" 2>/dev/null || fail "could not create $target. The storage volume is not writable by the container user. If you bind-mounted a host directory, chown it to $(id -u):$(id -g) on the host." +done + +########################################################################## +# Application key +########################################################################## +# Without this every session cookie and encrypted column is unreadable. It must +# be identical across web, worker and scheduler, which is why it is generated +# once by the installer into .env rather than per-container at boot. +if [ -z "$APP_KEY" ]; then + fail "APP_KEY is not set. Generate one with 'convoyctl artisan key:generate --show' and put it in your .env, then restart. All three Convoy containers must share the same key." +fi + +########################################################################## +# URL +########################################################################## +# Signed URLs (SSO deep links, password resets) and asset paths are all built +# from APP_URL. Left at the framework default, every emailed link points at +# localhost and the operator finds out from a customer. +case "${APP_URL:-}" in + ""|"http://localhost"|"http://localhost:"*) + fail "APP_URL is still the default (${APP_URL:-unset}). Set it to the URL customers reach this panel on, including the scheme, or password-reset and SSO links will point at localhost." + ;; +esac + +echo "✅ NOTICE ($script_name): preflight checks passed." diff --git a/docker/install.sh b/docker/install.sh new file mode 100644 index 00000000000..c50f0f1ecd4 --- /dev/null +++ b/docker/install.sh @@ -0,0 +1,217 @@ +#!/usr/bin/env bash +# +# Convoy installer. +# +# curl -fsSL https://install.convoypanel.com | sudo bash +# curl -fsSL https://install.convoypanel.com | sudo bash -s -- --domain panel.example.com --email you@example.com +# +# Installs Docker if it is missing, writes /opt/convoy, starts the stack and +# creates the first administrator. The buyer never has to know that any of this +# is Docker underneath -- which is the point. + +set -euo pipefail + +CONVOY_DIR="${CONVOY_DIR:-/opt/convoy}" +CONVOY_VERSION="${CONVOY_VERSION:-latest}" +CONVOY_REPO="${CONVOY_REPO:-https://raw.githubusercontent.com/ConvoyPanel/panel}" +DOMAIN="" +ADMIN_EMAIL="" +ASSUME_YES=0 + +readonly RED=$'\033[0;31m' GREEN=$'\033[0;32m' YELLOW=$'\033[0;33m' BOLD=$'\033[1m' DIM=$'\033[2m' RESET=$'\033[0m' + +info() { printf '%s\n' "${GREEN}==>${RESET} $*"; } +warn() { printf '%s\n' "${YELLOW}warning:${RESET} $*" >&2; } +die() { printf '%s\n' "${RED}error:${RESET} $*" >&2; exit 1; } + +usage() { + cat <<'EOF' +Convoy installer + + --domain Hostname or IP the panel will be reached on + --email
Email address for the first administrator + --version Image tag to install (default: latest) + --dir Install directory (default: /opt/convoy) + --yes Do not prompt; fail instead of asking + --help Show this message + +EOF +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --domain) DOMAIN="${2:?--domain needs a value}"; shift 2 ;; + --email) ADMIN_EMAIL="${2:?--email needs a value}"; shift 2 ;; + --version) CONVOY_VERSION="${2:?--version needs a value}"; shift 2 ;; + --dir) CONVOY_DIR="${2:?--dir needs a value}"; shift 2 ;; + --yes|-y) ASSUME_YES=1; shift ;; + --help|-h) usage; exit 0 ;; + *) usage; die "unknown option: $1" ;; + esac +done + +########################################################################## +# Preflight +########################################################################## +[[ "$(id -u)" -eq 0 ]] || die "run this as root (prefix the command with sudo)." + +[[ -e "$CONVOY_DIR/.env" ]] && die "a Convoy install already exists at $CONVOY_DIR. Use 'convoyctl upgrade' to update it, or pass --dir to install elsewhere." + +command -v curl >/dev/null 2>&1 || die "curl is required but not installed." + +# Caddy binds the host's 80 and 443. Finding out from a crash loop three minutes +# from now is a worse experience than finding out here. +for port in 80 443; do + if command -v ss >/dev/null 2>&1 && ss -Hltn "sport = :$port" 2>/dev/null | grep -q .; then + die "port $port is already in use. Convoy needs both 80 and 443. Stop the service using it (often an existing nginx or apache) and run this again." + fi +done + +prompt_for() { + local var="$1" flag="$2" message="$3" value="" + [[ -n "${!var}" ]] && return 0 + (( ASSUME_YES )) && die "$message (pass $flag when using --yes)." + [[ -t 0 ]] || die "$message (no terminal available; pass $flag instead)." + read -rp "$message: " value + [[ -n "$value" ]] || die "a value is required." + printf -v "$var" '%s' "$value" +} + +prompt_for DOMAIN --domain "Hostname or IP customers will reach this panel on" +prompt_for ADMIN_EMAIL --email "Email address for the administrator account" + +# Let's Encrypt cannot issue for a bare IP, so an IP silently means self-signed. +# Say so now rather than letting the operator wonder why the browser complains. +AUTO_HTTPS=on +if [[ "$DOMAIN" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ || "$DOMAIN" == *:*:* ]]; then + AUTO_HTTPS=off + warn "$DOMAIN is an IP address. Certificate authorities do not issue for bare IPs, so Convoy will serve a self-signed certificate and browsers will show a warning. Point a domain at this host and re-run with --domain to get a trusted certificate." +fi + +########################################################################## +# Docker +########################################################################## +if ! command -v docker >/dev/null 2>&1; then + info "installing Docker" + curl -fsSL https://get.docker.com | sh || die "Docker installation failed. Install it manually and re-run." +fi + +docker compose version >/dev/null 2>&1 || die "the Docker Compose plugin is missing. Install docker-compose-plugin and re-run." +systemctl enable --now docker >/dev/null 2>&1 || true + +########################################################################## +# Files +########################################################################## +info "writing $CONVOY_DIR" +mkdir -p "$CONVOY_DIR" + +# The compose file and the image have to come from the same release. `latest` is +# a published image tag, not a git ref, so resolve it to the tag it points at +# rather than pulling compose.yml off main and running a released image with it. +ref="$CONVOY_VERSION" +if [[ "$ref" == "latest" ]]; then + ref="$(curl -fsSL "https://api.github.com/repos/ConvoyPanel/panel/releases/latest" 2>/dev/null \ + | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -1)" + [[ -n "$ref" ]] || die "could not determine the latest Convoy release. Pass --version with an explicit tag (for example --version v5.0.0)." +fi + +curl -fsSL "$CONVOY_REPO/$ref/compose.yml" -o "$CONVOY_DIR/compose.yml" \ + || die "could not download compose.yml for version $CONVOY_VERSION." +curl -fsSL "$CONVOY_REPO/$ref/.env.docker.example" -o "$CONVOY_DIR/.env" \ + || die "could not download the environment template." + +# Neither alphabet below contains `$`, so nothing here can be mangled by +# Compose's interpolation of .env. 32 bytes is what Laravel's AES-256 key needs. +app_key="base64:$(openssl rand -base64 32)" +db_password="$(openssl rand -hex 24)" +admin_password="$(openssl rand -base64 18 | tr -d '/+=' | cut -c1-20)" + +scheme=https +set_env() { + local key="$1" value="$2" + # Values are written with a literal-safe replacement so slashes in a URL or + # key do not terminate the sed expression. + python3 - "$CONVOY_DIR/.env" "$key" "$value" <<'PY' +import sys, re +path, key, value = sys.argv[1], sys.argv[2], sys.argv[3] +with open(path) as fh: + text = fh.read() +pattern = re.compile(rf'^{re.escape(key)}=.*$', re.MULTILINE) +replacement = f'{key}={value}' +text, count = pattern.subn(lambda _: replacement, text, count=1) +if count == 0: + text = text.rstrip('\n') + f'\n{replacement}\n' +with open(path, 'w') as fh: + fh.write(text) +PY +} + +set_env APP_KEY "$app_key" +set_env APP_DOMAIN "$DOMAIN" +set_env APP_URL "$scheme://$DOMAIN" +set_env CONVOY_AUTO_HTTPS "$AUTO_HTTPS" +set_env CONVOY_VERSION "$CONVOY_VERSION" +set_env DB_PASSWORD "$db_password" +set_env MAIL_FROM_ADDRESS "convoy@$DOMAIN" + +chmod 600 "$CONVOY_DIR/.env" + +info "installing convoyctl" +curl -fsSL "$CONVOY_REPO/$ref/docker/convoyctl" -o /usr/local/bin/convoyctl \ + && chmod 755 /usr/local/bin/convoyctl + +########################################################################## +# Start +########################################################################## +cd "$CONVOY_DIR" + +info "pulling images (this takes a minute on a fresh host)" +docker compose pull --quiet + +info "starting Convoy" +docker compose up -d --remove-orphans + +info "waiting for the panel to come up" +waited=0 +until [[ "$(docker inspect -f '{{.State.Health.Status}}' "$(docker compose ps -q web)" 2>/dev/null)" == "healthy" ]]; do + if (( waited >= 300 )); then + docker compose logs --tail=50 web >&2 + die "the panel did not start within 5 minutes. The last 50 log lines are above." + fi + sleep 5 + waited=$(( waited + 5 )) +done + +########################################################################## +# First administrator +########################################################################## +info "creating the administrator account" +docker compose exec -T web php artisan users:create \ + --email "$ADMIN_EMAIL" \ + --name "Administrator" \ + --password "$admin_password" \ + --admin true >/dev/null || die "could not create the administrator. The panel is running; create one with: convoyctl artisan users:create" + +cat < run an Artisan command + +Configuration lives in ${BOLD}$CONVOY_DIR/.env${RESET}. +EOF + +if [[ "$AUTO_HTTPS" == "off" ]]; then + printf '\n%s\n' "${YELLOW}The certificate is self-signed. Your browser will warn on first visit.${RESET}" +fi diff --git a/dockerfiles/caddy/.gitignore b/dockerfiles/caddy/.gitignore deleted file mode 100644 index 6320cd248dd..00000000000 --- a/dockerfiles/caddy/.gitignore +++ /dev/null @@ -1 +0,0 @@ -data \ No newline at end of file diff --git a/dockerfiles/caddy/Caddyfile-development b/dockerfiles/caddy/Caddyfile-development deleted file mode 100644 index aea4b39401d..00000000000 --- a/dockerfiles/caddy/Caddyfile-development +++ /dev/null @@ -1,6 +0,0 @@ -{$APP_URL}, :80 { - root * /var/www/public - php_fastcgi php:9000 - encode gzip - file_server -} \ No newline at end of file diff --git a/dockerfiles/caddy/Caddyfile-production b/dockerfiles/caddy/Caddyfile-production deleted file mode 100644 index c4789cc40d0..00000000000 --- a/dockerfiles/caddy/Caddyfile-production +++ /dev/null @@ -1,12 +0,0 @@ -{$APP_URL} { - root * /var/www/public - php_fastcgi php:9000 - encode gzip - file_server - - @static { - file - path *.ico *.css *.js *.gif *.webp *.avif *.jpg *.jpeg *.png *.svg *.woff *.woff2 - } - header @static Cache-Control max-age=5184000 -} \ No newline at end of file diff --git a/dockerfiles/caddy/Dockerfile b/dockerfiles/caddy/Dockerfile deleted file mode 100644 index e600625124c..00000000000 --- a/dockerfiles/caddy/Dockerfile +++ /dev/null @@ -1,14 +0,0 @@ -FROM caddy:2.6-alpine - -ARG APP_ENV -ARG APP_URL - -COPY ./Caddyfile-* /etc/caddy/ - -RUN if [ $APP_URL = "http://localhost" ] || [ $APP_URL = "http://127.0.0.1" ] || [ $APP_URL = "https://localhost" ] || [ $APP_URL = "https://127.0.0.1" ]; then \ - cp /etc/caddy/Caddyfile-development /etc/caddy/Caddyfile; \ - elif [ $APP_ENV = "production" ]; then \ - cp /etc/caddy/Caddyfile-production /etc/caddy/Caddyfile; \ - else \ - cp /etc/caddy/Caddyfile-development /etc/caddy/Caddyfile; \ - fi \ No newline at end of file diff --git a/dockerfiles/mysql/.gitignore b/dockerfiles/mysql/.gitignore deleted file mode 100644 index 6320cd248dd..00000000000 --- a/dockerfiles/mysql/.gitignore +++ /dev/null @@ -1 +0,0 @@ -data \ No newline at end of file diff --git a/dockerfiles/php/Dockerfile b/dockerfiles/php/Dockerfile deleted file mode 100644 index 53d9e609854..00000000000 --- a/dockerfiles/php/Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM php:8.2-fpm-alpine - -ARG PHP_XDEBUG -ARG PHP_XDEBUG_MODE='debug' -ARG APP_ENV -ENV PHP_IDE_CONFIG="serverName=convoy" -ENV PHP_MAX_CHILDREN=100 - -ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ -RUN chmod +x /usr/local/bin/install-php-extensions && \ - install-php-extensions pdo_mysql pcntl redis opcache gmp - -RUN if [ $APP_ENV = "local" ]; then \ - echo "opcache.validate_timestamps=1" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache-cli.ini; \ - fi; - -RUN if [ $PHP_XDEBUG = "true" ]; then \ - install-php-extensions xdebug; \ - echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - echo "xdebug.mode=$PHP_XDEBUG_MODE" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - echo "xdebug.idekey=convoy" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - fi; - -RUN echo "pm.max_children = $PHP_MAX_CHILDREN" >> /usr/local/etc/php-fpm.d/zz-docker.conf - -WORKDIR /var/www - -CMD ["php-fpm"] \ No newline at end of file diff --git a/dockerfiles/workers/Dockerfile b/dockerfiles/workers/Dockerfile deleted file mode 100644 index 2a9d4464579..00000000000 --- a/dockerfiles/workers/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM php:8.2-fpm-alpine - -ARG APP_ENV - -COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/local/bin/ -RUN install-php-extensions pdo_mysql pcntl redis opcache -RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini -RUN if [ $APP_ENV = "local" ]; then \ - echo "opcache.validate_timestamps=1" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache-cli.ini; \ - fi; - -RUN apk add --no-cache bash logrotate supervisor - -COPY supervisord.conf /etc/supervisord.conf -COPY laravel-logrotate /etc/logrotate.d/laravel - -CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"] \ No newline at end of file diff --git a/dockerfiles/workers/laravel-logrotate b/dockerfiles/workers/laravel-logrotate deleted file mode 100644 index 804872e3bcb..00000000000 --- a/dockerfiles/workers/laravel-logrotate +++ /dev/null @@ -1,9 +0,0 @@ -/var/www/storage/logs/laravel.log { - maxsize 50M - hourly - missingok - rotate 8 - compress - notifempty - su root adm -} \ No newline at end of file diff --git a/dockerfiles/workers/supervisord.conf b/dockerfiles/workers/supervisord.conf deleted file mode 100644 index 4faeff3ebe9..00000000000 --- a/dockerfiles/workers/supervisord.conf +++ /dev/null @@ -1,38 +0,0 @@ -[supervisord] -user=root -loglevel=warn -nodaemon=true -logfile=/var/www/storage/logs/supervisord.log -pidfile=/var/www/storage/logs/supervisord.pid - -[rpcinterface:supervisor] -supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface - -[supervisorctl] -serverurl=unix:///tmp/supervisor.sock - -[program:horizon] -process_name=%(program_name)s -command=php /var/www/artisan horizon -autostart=true -autorestart=true -user=root -redirect_stderr=true -stdout_logfile=/var/www/storage/logs/horizon.log -stopwaitsecs=3600 - -[program:scheduler] -process_name=%(program_name)s_%(process_num)02d -command=/bin/sh -c "while [ true ]; do (php /var/www/artisan schedule:run --verbose --no-interaction &); sleep 60; done" -autostart=true -autorestart=true -user=root -numprocs=1 -redirect_stderr=true -stdout_logfile=/var/www/storage/logs/scheduler.log - -[program:logrotate] -command=logrotate /etc/logrotate.conf -autostart=true -autorestart=true -redirect_stderr=true \ No newline at end of file diff --git a/dockerfiles/workspace/Dockerfile b/dockerfiles/workspace/Dockerfile deleted file mode 100644 index 08b85ae0337..00000000000 --- a/dockerfiles/workspace/Dockerfile +++ /dev/null @@ -1,41 +0,0 @@ -FROM php:8.2-bullseye - -ARG PHP_XDEBUG -ARG PHP_XDEBUG_MODE='debug' -ENV PHP_IDE_CONFIG="serverName=convoy" - -ENV TZ=UTC -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone - -RUN apt-get update -RUN apt-get -y install ca-certificates gnupg software-properties-common curl sudo unzip default-mysql-client - -RUN sudo mkdir -p /etc/apt/keyrings; \ - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg; \ - NODE_MAJOR=20; \ - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list; \ - apt-get update; \ - sudo apt-get install nodejs -y; - -ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ -RUN chmod +x /usr/local/bin/install-php-extensions && \ - install-php-extensions pdo_mysql pcntl redis opcache gmp -RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini; \ - echo "opcache.validate_timestamps=1" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache-cli.ini; - -RUN if [ $PHP_XDEBUG = "true" ]; then \ - install-php-extensions xdebug; \ - echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - echo "xdebug.mode=$PHP_XDEBUG_MODE" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - echo "xdebug.idekey=convoy" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ - fi; - -RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"; \ - php composer-setup.php; \ - php -r "unlink('composer-setup.php');"; \ - sudo mv composer.phar /usr/local/bin/composer; - -RUN echo "alias art='php artisan'" >> ~/.bashrc - -WORKDIR /var/www diff --git a/docs/anchor-enrollment-plan.md b/docs/anchor-enrollment-plan.md new file mode 100644 index 00000000000..5d5a06d4423 --- /dev/null +++ b/docs/anchor-enrollment-plan.md @@ -0,0 +1,542 @@ +# Anchor-first node enrollment — plan + +Turn "add a node" from a fourteen-field form into one command run on the host, +the way Tailscale adds a machine. Written 2026-08-20. + +The framing that drives the whole design: **an anchor is a machine, a node is a +role that machine takes on.** Every node has an anchor; not every anchor is a +node (a relay is an anchor that never becomes one). Today the schema says the +opposite — `nodes.anchor_id` makes the anchor an accessory bolted onto a node +that already exists. + +**The destination is a required anchor** — `nodes.anchor_id` NOT NULL, the +manual create path gone, and the branching that supports both worlds deleted. +This plan gets there in stages rather than in one migration, because the +constraint is cheap once the population is clean and dangerous while it is not. +Slices 1–5 are the enrollment feature; ["Getting to required"](#getting-to-required) +is the ladder to the constraint, and it is where the v4 upgrade question is +answered. + +## The problem + +Adding a node today is a manual transcription exercise, and every field is +something the host already knows: + +| Field | Where the operator gets it | Who actually knows it | +| --- | --- | --- | +| `fqdn`, `port` | typed | the host | +| `name` (PVE node name) | typed, must match exactly | the host | +| `token_id` / `token_secret` | created in the PVE UI, pasted | the host | +| `rootPrivileges`, `privilegeSeparationDisabled` | **two checkboxes the operator ticks to attest** they did it right | the host | +| `socket_count`, `core_count`, `cpu_count`, `memory` | typed, never re-checked | the host | +| `location_id`, `display_name`, `memory_overallocate` | genuine operator policy | the operator | + +Only the last row is a real decision. Everything above it is dictation, and two +of those fields are attestations — `z.literal(true)` checkboxes +(`features/nodes/api.ts:48`) that promise the pasted token is `root@pam` with +privilege separation off. Nothing verifies that; a wrong tick surfaces later as +a confusing permission error. + +The hardware columns are worse than tedious: nothing ever writes `socket_count` +after creation (`grep socket_count app/` finds only the model and the DTO), so +a RAM upgrade silently leaves the panel scheduling against stale capacity. + +Meanwhile the anchor enrollment flow already proves the pattern works — it just +runs in the wrong direction. + +## What exists (and why it's the wrong direction) + +`AnchorEnrollmentService` + `EnrollmentController` implement a **pre-registration +claim**: the operator creates the `Anchor` row first (name, mode, `public_url`), +the panel mints a token *bound to that row*, and the agent exchanges it for +config. The token identifies a record that already exists. + +Tailscale's auth key is the inverse: the key is bound to *nothing*, and the +machine that presents it **creates its own record** out of what it reports about +itself. That inversion is the entire feature. Everything else here follows from +it. + +Worth keeping from what's built: the config-writing agent side +(`anchor enroll`, atomic `0600` write), secret rotation on every enroll (the +remediation story is already correct), the `uuid.secret` bearer scheme, and the +heartbeat loop. None of that changes. + +## Design + +### 1. Enrollment keys replace per-anchor tokens + +New table `anchor_enrollment_keys`: + +``` +id, uuid, name, token_hash (sha256, unique), created_by +mode -- 'agent' | 'relay' | null (either) +max_uses, uses -- null max = reusable without limit +expires_at, revoked_at +auto_approve -- bool, default FALSE +default_location_id -- nullable FK; the one policy field a key can pre-answer +default_relay_id -- nullable FK +timestamps +``` + +The existing `anchors.enrollment_token_hash` / `enrollment_expires_at` columns +**stay**. They are still the right mechanism for the other job: rotating one +existing installation's secret. Two different questions — "let a new machine +in" versus "re-key this machine" — deserve two different credentials, and +conflating them is what makes the current flow un-invertible. + +Defaults: single use, 15 minutes (matching today), `auto_approve = false`. A key +that creates nodes is a far stronger credential than today's token, which could +only claim one pre-made row. It should behave like one. + +### 2. The agent reports facts; the panel decides policy + +`anchor enroll` keeps its exact CLI shape. The request body gains a +self-report, and the **panel** decides from the token's shape whether it is a +targeted rotation or a key-based enrollment. Old tokens keep working; no CLI +churn, no flag to explain. + +```jsonc +{ + "token": "…", + "mode": "agent", + "report": { + "hostname": "pve1.example.com", + "pve_node_name": "pve1", // must match nodes.name exactly + "pve_version": "9.2.2", + "cluster_name": "prod", + "cluster_ca_fingerprint": "…", // the identity ClusterIdentityService trusts + "cpu": { "sockets": 2, "cores": 32, "threads": 64 }, + "memory_bytes": 549755813888, + "addresses": ["10.0.0.11", "2001:db8::11"], + "version": "0.1.0", + "protocol": { "min": 1, "max": 1 }, + "capabilities": ["console.qemu.vnc", "console.qemu.terminal", "templates.install"] + } +} +``` + +Hard rule: **a self-report may never grant privilege.** It fills in facts about +hardware and identity. `location_id`, `memory_overallocate`, and the overage +penalty stay operator policy, supplied by the key's defaults or at approval. +A host that lies about its RAM under-schedules itself; a host that could pick +its own location picks its blast radius. + +### 3. The agent mints its own PVE API token + +This is the field that makes the difference between "shorter form" and "no +form", and it is available only because the agent already runs as root on the +host with `qm`/`/etc/pve` access. + +At enroll time the agent runs the equivalent of: + +``` +pveum user token add root@pam convoy- --privsep 0 +``` + +and returns `token_id` + `token_secret` in the report. The panel stores them in +the columns it already has — `ProxmoxClient` is untouched. The two attestation +checkboxes disappear, because the thing they attested to is now *constructed* +rather than promised. + +Three things this must get right: + +- **Idempotency.** The secret is shown only at creation, so a name collision + means remove-then-add, not "reuse". Name the token after the installation id + so re-enrolling a rebuilt host is unambiguous. +- **Never hard-fail the enrollment on it.** If `pveum` is missing or refuses, + the anchor still enrolls and the node lands needing credentials, with the + paste field as the fallback. A console-capable agent with no API token is + strictly better than no agent. +- **`ProtectSystem=strict` with no `ReadWritePaths`.** The shipped unit + (`packaging/systemd/anchor.service:30`) mounts the filesystem read-only with + no exemptions, so writes to `/etc/pve` are already a live question — as are + template installs writing to `/var/lib/vz/dump`. This is remaining-work item + 2 in the anchor handoff and credential minting makes it blocking. Add + `ReadWritePaths=/etc/pve /var/lib/vz/dump` and verify on a real node. + +### 4. Enrollment creates the Anchor; approval creates the Node + +The split that keeps the schema honest, and the direct answer to "not all +anchors are nodes": + +- **Enroll** → `Anchor` row, secret issued, heartbeats start, `approved_at` + null. The report is parked in a new `anchors.reported_facts` json column. + The panel refuses to mint console sessions until approved. +- **Approve** (or `auto_approve` on the key, which makes it one step) → the + `Node` row is created from the parked report plus the location. + +The alternative — create the node immediately in a pending state — forces +`nodes.location_id` nullable and puts half-real rows into every node query, +placement scan, and capacity sum. Better to keep the node table meaning +"nodes we actually run servers on" and let the anchor carry the not-yet state. +A relay simply never reaches step two, which is the model saying out loud that +a node is a role rather than a kind of thing. + +`nodes.anchor_id` gains a unique index — an agent runs `qm` locally, so it can +only ever serve its own host. Postgres permits many NULLs under a unique index, +so grandfathered rows (below) are unaffected. + +### 5. Re-enrollment reconciles instead of duplicating + +Key: `(cluster_ca_fingerprint, pve_node_name)`, falling back to +`pve_node_name` for a standalone host. A rebuilt or re-keyed machine matching +an existing node **adopts** it — new secret, same node, same servers — rather +than creating a duplicate that quietly competes for the same VMIDs. +`ClusterIdentityService` already treats the CA fingerprint as the only +trustworthy cluster identity, including its "separated node keeps the old CA" +caveat; reuse that judgment rather than re-deriving it. + +Cross-check the report once credentials work: if the agent claims node `pve1` +in cluster X and the PVE API disagrees, flag for a human. The existing +`member_names` tripwire is the precedent. + +### 6. `fqdn` and `public_url` + +Two different reachability questions, and the agent can only guess at either. + +- **`fqdn`** (panel → PVE API): the agent proposes candidates, and the panel + adds one it can actually trust — **the source IP of the enrollment request**. + Then it *validates* by connecting, using `NodeConnectionTestService`, before + accepting. If nothing connects, approval stalls with the candidates listed + rather than saving a value that looks fine and fails at first use. +- **`public_url`** (panel → anchor): stop writing it into the agent config + entirely. `grep` shows the agent never reads it — it is panel-side data that + got mirrored into the TOML. Keeping it panel-only means the panel can correct + it later without re-enrolling. + +### 7. Being honest about "Tailscale style" + +This gets Tailscale's *onboarding* ergonomics: one command, no form. It does +**not** get Tailscale's *networking* ergonomics. The relay still dials the +agent's WebSocket URL, so an agent must be inbound-reachable — the very thing +`public_url` exists to describe, and the reason a NAT'd host still needs work. + +Removing that means the agent holding a multiplexed outbound connection the +panel dials back through — protocol v2, and a much bigger change. The agent's +heartbeat loop is the natural seam for it. **Keep these sequenced, not merged.** +Enrollment is worth shipping on its own, and conflating them turns a two-week +feature into a protocol rewrite. + +Cheap down payment while we're in here: let the heartbeat response carry a +config revision instead of `204`, so the panel can hand down corrected settings +(a reassigned relay, a fixed `public_url`) without an operator re-running +anything. + +## Migration from v4 — the constraint is the destination, not the migration's job + +A required anchor is where this ends up (see "Getting to required" below). What +it must not be is *the thing the v4 cutover runs into*. + +`NOT NULL nodes.anchor_id` applied during the upgrade would force the cutover to +invent a placeholder anchor per node — a row that never heartbeats, never +enrolls, and satisfies the constraint while describing nothing. That is strictly +worse than a null, and it would bake the upgrade moment into the schema forever. +A null says "no anchor yet" accurately, and every part of the panel that needs an +anchor (console sessions, template installs) has to handle its absence anyway, +because an anchor can go offline at any moment. + +So for the cutover release the rule is **required by construction, not by +constraint**: + +- `nodes.anchor_id` stays nullable, exactly as `2026_07_17_010000` left it. +- Enrollment becomes the only *supported path* for adding a node in the UI — + "Enroll a node" is the primary action, with "add manually" demoted to an + escape hatch for hosts that cannot run the agent. +- `POST /api/application/nodes` keeps accepting a full manual payload for now. + +The general principle, which the ladder below is built on: **never migrate into +a constraint.** Migrate the population first; add the constraint later, when it +is already a no-op on every row. + +### What the v4 operator actually experiences + +The cutover in `database/cutover/RUNBOOK.md` is unchanged — pgloader for the +engine, `artisan migrate` for the renames. Nodes arrive with `anchor_id = NULL` +and **keep working**: they poll, they place servers, they run backups. What +they lack is console and template installs, which is exactly what they lacked +in v4 (Coterm, now removed). + +Then adoption is the same one command, because §5's reconciliation makes +"enroll a new node" and "adopt an existing one" the same endpoint: + +1. The nodes list shows unlinked nodes with an "Install Anchor" action. +2. It issues an enrollment key and shows the command. +3. The agent enrolls, reports `pve_node_name` + cluster fingerprint, matches + the existing row, and links itself. +4. It mints a fresh PVE token, replacing the v4 credentials the operator + pasted years ago. + +Incremental, per node, no maintenance window, no fleet-wide flag day. An +operator who adopts three of twelve nodes has three nodes with consoles and +nine that work exactly as they did — which is the property that makes it safe +to ship before every operator is ready. + +Deliberately **not** doing, at any stage: a migration that auto-creates anchors +to satisfy a constraint. A placeholder anchor encodes the upgrade moment into +the data forever to save an operator one command. + +Note the difference between that and stage B's grandfathering below, which is +the opposite move: stage B changes no rows at all, it only stops *new* ones from +being created without an anchor. Grandfathering existing data is fine; +fabricating data to look enrolled is not. + +## Getting to required + +The goal is a required anchor, for the simplification it buys. The way to get +there without a hazardous migration is a ladder pegged to release boundaries, +where each rung is separately shippable and reversible. + +### Stage A — v5.x: enrollment ships, column nullable + +Slices 1–5. Unlinked nodes work exactly as they do today and are nagged in the +UI. Add `php artisan anchor:preflight`, which prints how many nodes are +unlinked and the command to fix each. This is the *same* command later stages +gate on, so it earns its keep long before it is load-bearing. + +### Stage B — v5.x+n: required by policy + +`AnchorSettings::require_anchors` (bool). When on, node creation without an +anchor is rejected — UI and API both — and the manual create form is gone. +Existing unlinked nodes keep running untouched. + +The flag gates **creation, not existence**. That distinction is the whole +reason this rung is safe: an operator can turn it on today without auditing +their fleet, because nothing they already have breaks. + +Default it by looking at the data, in the migration that adds it: + +```php +// Fresh installs get the simple world immediately. An upgraded install with +// unlinked nodes gets the flag off, because turning it on for them would be a +// policy decision made on their behalf about hosts we have never seen. +$default = DB::table('nodes')->whereNull('anchor_id')->doesntExist(); +``` + +That is "required by default" delivered literally: on by default where it costs +nothing, off where it would surprise someone, and a single switch in settings +once they have finished enrolling. + +### Stage C — v11.0 (major): required by constraint + +`NOT NULL` plus `restrictOnDelete` (replacing `nullOnDelete`). The migration's +job is to **verify, not repair**: it runs the preflight and aborts with the list +of offending nodes and the remediation command if any remain. A major release is +allowed to require work before upgrading; a minor is not. Nothing is auto-created +to satisfy it, ever. + +Only after the constraint lands does the code deletion happen — that is the +payoff, and doing it earlier means maintaining both worlds while claiming one. + +### What actually gets simpler + +Deleted at stage C: + +- The manual node form, `StoreNodeRequest`'s credential and spec rules, and the + two `z.literal(true)` attestation checkboxes. +- `AnchorController::syncNodes()` and `node_ids` on `AnchorFormRequest` — + assignment stops being an operation; enrollment is the only way a node and an + anchor meet. +- `Anchor::nodes()` HasMany → HasOne. The `AnchorPicker` on the node form, the + nullable `anchor_id` filter, and `EnrollmentPanel`'s two entry points collapse + to one. +- The app-level "Detach this Anchor before deleting it" guard, which the FK now + enforces. +- `ServerController::console`'s absent-anchor branch, and its equivalents in + `AnchorSessionService` and the template-install path. + +**What does not get simpler, and should not be expected to:** every liveness +branch stays. `compatibility()` still returns UNENROLLED / OFFLINE / +INCOMPATIBLE, and console minting still has to handle "the anchor exists and is +down". *Required is not the same as reachable.* The null check is the small half +of that branching; the health check is the large half and it is permanent. + +Test cost is smaller than it looks: 56 `Node::factory()` call sites across 26 +files, but `NodeFactory` sets `anchor_id => null` in one place. Point that +default at an agent anchor and most call sites keep working untouched. + +### The one real casualty: `POST /api/application/nodes` + +Convoy serves **two API surfaces from one set of route definitions**. +`bootstrap/app.php:55-64` loads `routes/api-admin.php` a second time under +`/api/application` behind a Sanctum guard — "one source of truth", in its own +words. So this single line (`routes/api-admin.php:87`): + +```php +Route::post('/', [Admin\Nodes\NodeController::class, 'store']); +``` + +is simultaneously two endpoints: + +- `POST /api/admin/nodes` — the browser SPA, session auth +- `POST /api/application/nodes` — **external bearer tokens** holding + `nodes:write` + +The second is a real public endpoint, not a theoretical one: `nodes` is in +`TokenAbilities::RESOURCES`, and the only route in the file that opts out of +token access is `/tokens` (`routes/api-admin.php:365`). Anything integrating +with Convoy — Terraform, provisioning scripts, a billing module — registers +nodes through it today. + +**Why stage C necessarily removes it.** Once a node requires an anchor, and an +anchor is by definition *the identity of a daemon that presented a key and +proved it is running*, an API client has nothing to put in that field. +"Create a node" from a JSON payload stops being restricted and starts being +**unrepresentable** — there is no anchor for the payload to reference, and no +honest way to invent one (that is the placeholder-row problem again). + +So the constraint that deletes an admin form also deletes a public endpoint. +The form has a replacement the operator can see — run one command. The API +client needs one too, and "run a command" is not available to it. + +**The replacement.** The client creates an *enrollment key* and hands it to +whatever builds the host — cloud-init, Ansible, a Proxmox autoinstall answer +file: + +``` +POST /api/application/anchor-enrollment-keys → { token, expires_at } + ↓ baked into the host build +anchor enroll --panel-url … --token … (runs on first boot) + ↓ +the node exists, with its specs, credentials and console already correct +``` + +The automation still works end to end. What changes is the shape: from +*declaring a node* to *authorizing a machine to declare itself*. Terraform users +will find it familiar, because it is what the Tailscale provider does — +`tailscale_tailnet_key`, not `tailscale_device`. And it rides the `anchors` +ability already in `TokenAbilities::RESOURCES`, so it adds an endpoint rather +than a permission vocabulary. + +**Why it has to ship a minor early.** There must be one release where *both* +paths work, so integrations can move to keys while `POST /nodes` still answers. +Ship the key endpoint and the removal together and every integration breaks on +upgrade day, with the fix in the same release note nobody read yet. That +overlap window is the real reason stage C is pegged to a major instead of being +folded into stage B. + +### Preconditions for stage C + +1. **The key endpoint above shipped a full minor earlier**, with the overlap + window served. +2. **`ON DELETE` flips** to `restrict`. +3. **The FK should only ever point at an agent-mode anchor.** Today that is + app-level (`syncNodes()` early-returns for relays). A CHECK cannot reach + another table, so the DB-level options are a trigger or a denormalised mode + column — neither is worth it. Keep it app-level with an explicit test, and + note the gap rather than pretending the constraint covers it. +4. **Preflight is documented in the upgrade notes**, not just executed by the + migration, so an operator meets the requirement before the maintenance + window rather than inside it. + +## Slices + +1. **Enrollment keys — DONE.** `anchor_enrollment_keys`, model + derived + `EnrollmentKeyStatus`, admin CRUD under `/api/admin/anchors/enrollment-keys`, + and three audit events. Tokens still claim pre-made anchors — no behaviour + change yet, which is what let it land green on its own (724 pest tests pass). + + Three decisions taken while building it, none of which the plan had settled: + + - **`auto_approve` / `default_location_id` / `default_relay_id` are not in + the table yet.** They are instructions to an enrollment handler that does + not exist until slice 2, and a CRUD surface that accepts settings nothing + honours is an API that lies. They arrive in the slice that reads them — + `2026_08_02_000000_add_panel_url_override_to_anchors` is the local + precedent for adding a column with the feature that needs it. + - **Revoke and delete are separate actions.** `POST /{key}/revoke` withdraws + the key and keeps the row; `DELETE /{key}` refuses anything still ACTIVE. + Otherwise deleting is a quieter revocation, and the quiet path is the one + taken when someone would rather the incident left no roster entry. + - **The token prefix is the discriminator slice 2 needs.** Keys are + `anc_key_…`, rotation tokens `anc_enroll_…`, so the enroll endpoint can + tell "re-key a known installation" from "admit a stranger" without that + answer depending on a database lookup succeeding. + + Unlimited uses and no expiry are both expressible — a machine image needs + them — but only by passing an explicit `null`. Omitting either field gives + the safe shape, so the dangerous one cannot be reached by forgetting a + parameter. +2. **Self-registration — DONE.** Key-based enrollment creates the `Anchor` + (`reported_facts`, `approved_at`, `enrollment_key_id`), approval accepts it, + and session minting gates on approval. Agent gathers and sends the report. + + What the build settled that the plan had not: + + - **Approval had to land in this slice, not slice 3.** Without it a + self-registered Anchor could never leave the pending state, so the slice + would have shipped a dead end. Slice 3 now adds *node materialization on + top of* an approval step that already exists, rather than inventing one. + - **`anchors.public_url` is nullable.** A machine that just introduced itself + has not been told how the panel reaches it back. The alternative -- deriving + a guess from the request's source address -- puts an unvalidated value in + the column the console dials, where it looks settled and fails at first + use. Approval is where it stops being null, which is also why approval + requires it. + - **`PENDING_APPROVAL` is asked before liveness.** A machine waiting to be + let in is heartbeating perfectly well; reporting it as unreachable sends an + operator to the network instead of to the queue holding the decision. + - **The self-enrollment audit event stayed under `admin.anchor.`** even + though no admin performed it. Areas are a closed, frontend-matched set, and + filtering `area=admin.anchor` now returns an installation's whole story. + That nobody did it is carried by the row having no actor. + - **The agent does not report the PVE version or the cluster CA + fingerprint.** Both come back from the Proxmox API over an authenticated + channel through code the panel already has and tests + (`ClusterIdentityService`); parsing them out of `/etc/pve` would be a + second implementation of an answer we can ask for. Host addresses are + likewise omitted -- the panel records the source address it actually + observed, which is the one reachability claim a machine cannot overstate. + + **Follow-up worth tracking:** `/api/anchor/enroll` is throttled to 10/minute + per IP. A rack booting from one image behind a single NAT can exceed that, so + the agent should back off and retry on 429 rather than the limit being + raised. +3. **Node materialization.** Approval queue UI; approve → create the node from + the report + location. `auto_approve` collapses it to one step. Unique index + on `nodes.anchor_id`. +4. **Credential minting.** Agent creates the PVE token; `ReadWritePaths` fixed + and verified on a live node; the two attestation checkboxes deleted. Paste + fallback retained. +5. **Adoption + reconciliation.** Fingerprint/name matching, re-enroll adopts, + cross-check against the PVE API, unlinked-node nudge on the nodes list, and + `anchor:preflight`. This is the slice v4 operators need; nothing before it is + wasted on them. + +Stage A ends here. The rungs to required follow on their own release cadence: + +6. **Enrollment keys in the Application API** (`POST + /api/application/anchor-enrollment-keys`) — the replacement for + `POST /api/application/nodes`, which stage C deletes. Must ship a full minor + before 8 so both paths overlap for one release. +7. **`require_anchors` setting** — stage B. Gates creation only; defaults from + the data. +8. **`NOT NULL` + `restrictOnDelete`** — stage C, a major. Verify-and-abort + migration, then the code deletion listed above. +9. *(separate track)* Reverse tunnel, protocol v2. Not part of this plan. + +Slices 1–3 are shippable without 4; an operator who pastes a token still skips +the other thirteen fields. Slices 6–8 are worth starting only once real +installs have run 1–5, because the argument for the constraint is that nobody +is relying on the nullable case any more — and that is an observation, not a +prediction. + +## Tests worth writing first + +- Key consumption: single-use, `max_uses`, expiry, revoked, wrong `mode`. +- A report cannot set `location_id`, `memory_overallocate`, or the overage + penalty — assert it directly, since this is the security boundary. +- Re-enroll of a known `(fingerprint, node name)` adopts; an unknown one + creates; a mismatched claim flags. +- Credential minting failure still yields a usable anchor. +- v4 shape: a node with `anchor_id = NULL` polls, places, and backs up; only + console and template install decline, with a message naming the reason. + +For the later rungs: + +- `require_anchors` on rejects anchorless creation via **both** `/api/admin` and + `/api/application` (one route definition, two guards — a test that only covers + the admin path proves nothing about the API), and leaves existing unlinked + nodes fully operational. +- The stage-C migration aborts and changes **nothing** when an unlinked node + exists — assert the row count and the nullability are both untouched after the + failure, not just that it threw. diff --git a/docs/audit-log-plan.md b/docs/audit-log-plan.md new file mode 100644 index 00000000000..0517f7a6c6e --- /dev/null +++ b/docs/audit-log-plan.md @@ -0,0 +1,341 @@ +# Audit logging — plan + +Covers GitHub #53 (client-side audit logging), widened during design to a +panel-wide audit trail: client server actions, account/security events, admin +panel actions, and API-token attribution. Written 2026-08-17. + +**All six slices are implemented.** Changes made while building are marked +"revised in build" below. + +## The state we are starting from + +There is an activity-log system in the tree, ported from Pterodactyl in 2022. +It has never been wired up and it does not work: + +- **Nothing calls it.** There are zero `Activity::` call sites outside the + facade itself. `ActivityController` (`Client/Servers/ActivityController.php`) + has no route pointing at it. +- **The schema and the code disagree.** Migration + `2022_11_02_223634_refactor_activity_logs_table` dropped `created_at` / + `updated_at` in favour of a `timestamp` column, but + `ActivityLog::prunable()` still filters on `created_at` and + `ActivityLogData::fromModel()` still reads both. The daily `PruneCommand` + registered at `routes/console.php:39` therefore throws every night. +- **The writer would fail on first use.** `ActivityLogService::getActivity()` + mass-assigns `api_key_id`, which is not a column on `activity_logs`. + +So this is a rebuild, not a revival. Both tables are empty, which means there is +no data to migrate and no compatibility to preserve. + +### Do not confuse this with the PVE task log + +`app/Enums/Activity/{Status,TaskStatus,TaskExitStatus}.php`, +`app/Data/Server/Proxmox/Activity/*` and +`app/Services/Proxmox/Server/ProxmoxActivityClient.php` are Proxmox *task* +plumbing that happens to share the word "activity". They are live and unrelated. +Leave them alone. + +## Decisions + +| Question | Decision | +| --- | --- | +| Foundation | Thin in-house, no `spatie/laravel-activitylog` | +| Event text | Enum key in the DB, copy rendered on the frontend | +| Call sites | Explicit `Audit::record(...)`, backed by a coverage test | +| Client sees staff actions | Per-event `visibility()`; identity masked by an operator setting | +| Retention | Tiered per-event: security forever, ops pruned | +| v1 surfaces | Client server Activity tab + global admin log | + +### Why not spatie + +Closer than it first looks — its `LogsActivity` auto-diff trait is opt-in, so +"it would log noise" is not a real objection. The actual reason is that we would +customise most of what it provides: its schema has no `ip`, `user_agent` or +token column (a follow-up migration plus a subclassed model), its +`description` column is non-nullable and pointless under enum-key rendering, and +its cleanup command has a single global window where we want tiered retention. +That leaves the `Activity` model's query scopes and a batch UUID helper as the +net gain, which is not worth a dependency to carry across Laravel upgrades. + +### Single subject, not many + +The Pterodactyl port models subjects as a many-to-many +(`activity_log_subjects`). With panel-wide scope, "subject = the thing acted +on, actor = who acted" covers every case in the list — a user's own events are +reachable by actor, a server's by subject. Drop the join table. + +## Schema + +One new migration: drop `activity_logs` and `activity_log_subjects`, create +`audit_logs`. The three 2022 migrations stay in the tree untouched. + +``` +id bigint +batch uuid, nullable +event string -- AuditEvent value, e.g. server.power.start +actor_type/id morph columns, nullable -- User or SystemActor; null only if unattributable +actor_label string nullable -- the actor's display name, copied at write time +api_token_id foreignId nullable -- personal_access_tokens, nullOnDelete +subject_type/id morph columns, nullable -- Server, Node, User, token, ... +ip string(45) nullable -- 45 fits IPv6 +user_agent string(500) nullable +properties json +created_at timestamp +``` + +Rows are immutable, so there is no `updated_at` — set `const UPDATED_AT = null` +on the model rather than disabling timestamps wholesale, so `created_at` is +still managed for us. This is the specific drift that broke the old system; +using the Laravel convention instead of a bespoke `timestamp` column avoids +repeating it. + +Indexes: `(subject_type, subject_id, created_at)` for the server tab feed, +`(actor_type, actor_id, created_at)` for per-user views, `(event)` and +`(created_at)` for filtering and pruning. The morph columns are declared by hand +rather than through `nullableNumericMorphs()`, because that helper adds its own +`(type, id)` index which is a strict prefix of the composites above — pure write +overhead on an append-only table. + +### actor_label, and why it is denormalised (revised in build) + +**Nothing in this panel uses `SoftDeletes`.** The plan originally specified +`morphTo()->withTrashed()` on the actor, copying the old Pterodactyl port — but +that is a no-op here, and it means deleting a user silently anonymises every +action they ever took. An audit log that forgets who acted the moment you delete +the account is not an audit log, and `admin.user.deleted` is retained forever +precisely so that record survives. + +So the actor's display name is copied onto the row at write time. The morph stays +(it resolves while the actor exists, and drives the actor filter); `actor_label` +is the snapshot of who they were then. `actor_id` is also still readable after +deletion, so entries by the same removed account remain correlatable. + +The alternative — making `User` soft-delete — is a much larger behavioural change +across the panel and is not worth it for this. + +## The event catalog + +`app/Enums/Audit/AuditEvent.php`, string-backed, dot-namespaced by area: + +```php +enum AuditEvent: string +{ + case SERVER_POWER_START = 'server.power.start'; + case SERVER_REINSTALLED = 'server.reinstalled'; + case ACCOUNT_PASSWORD_UPDATED = 'account.password.updated'; + case ADMIN_NODE_DELETED = 'admin.node.deleted'; + // ... +} +``` + +Case names are `SCREAMING_SNAKE_CASE`, matching every other enum in `app/Enums`. +Values are `area.thing.verb`, or the shorter `area.verb` where there is no +intermediate noun worth naming (`server.renamed`, `auth.logout`). + +The catalog was built from the actual route table rather than from imagination: +105 mutating routes under `api/client` and `api/admin`, plus the `api/auth` +endpoints. Note that `api/application/*` is a token-authenticated mirror of +`api/admin/*` served by the **same controllers**, so one call site covers both +surfaces and the actor resolves to a `User` or a `SystemActor` accordingly. + +Two metadata methods, each written as "sensible default plus an explicit +exception list" so adding an event needs no thought in the common case: + +```php +public function retention(): AuditRetention +{ + return match ($this) { + self::ACCOUNT_PASSWORD_UPDATED, + self::ACCOUNT_TWO_FACTOR_DISABLED, + self::ACCOUNT_API_KEY_CREATED, + /* ... security events ... */ => AuditRetention::FOREVER, + default => AuditRetention::STANDARD, + }; +} + +public function visibility(): AuditVisibility +{ + return match ($this) { + // The one exception so far: it reveals that the panel minted a token + // capable of impersonating the user. + self::ADMIN_USER_SSO_TOKEN_GENERATED => AuditVisibility::ADMIN_ONLY, + default => AuditVisibility::CLIENT, + }; +} +``` + +The enum auto-transforms into an exhaustive TypeScript string union in +`resources/scripts/types/generated.d.ts` (confirmed: `App\Enums\*` enums already +land there without an attribute). Typing the frontend copy map as +`Record ReactNode>` therefore makes a PHP event with no +matching copy a **type error**, closing the "forgot the wording" loop the same +way the coverage test closes "forgot to log it". + +## The recorder + +`app/Services/Audit/AuditLogger.php`, reached through an `Audit` facade so call +sites stay one line. **Revised in build:** the facade is `Audit`, not `AuditLog`, +so it does not collide with the model of that name — the two would otherwise need +aliasing in every file that touches both. + +```php +Audit::record( + AuditEvent::ServerPowerStart, + subject: $server, + properties: ['signal' => 'start'], +); +``` + +- **Actor** resolves to the explicit argument, else `auth()->user()`, else null. + Note that `auth()->user()` already returns a `SystemActor` (not a `User`) for + panel-wide application tokens — see `AdminAuthenticate` and + `CreateApplicationTokenService` — so the morph must be typed + `User|SystemActor` and the frontend must render a `SystemActor` actor as + "System". A null actor should mean *unattributable*, e.g. the scheduler, and + should be rare enough to be suspicious. +- **Token attribution** reads `$request->user()?->currentAccessToken()?->id`, so + a leaked key's blast radius is visible without a separate code path. +- **Request metadata** (ip, user agent) is captured automatically and is null in + console and queue contexts. **Revised in build:** that context check keys off + whether a route has actually been resolved. Neither `runningInConsole()` nor the + presence of `REMOTE_ADDR` can tell the difference — outside a real request the + container still hands back a synthetic `Request` whose `ip()` is `127.0.0.1`, + and both signals are also true under the test runner. Recording a scheduled + prune as having come from localhost would be a lie in the audit trail. +- **Never breaks the action.** The write is wrapped in try/catch: rethrow + outside production, `Log::error` in production. This one behaviour is worth + keeping from the old port. +- **Batching.** `AuditLog::batch(fn () => ...)` shares one UUID across the rows + a single user action produces (bulk deletes and the like), with a nesting + counter. Ported in spirit from `ActivityLogBatchService`, folded into the + logger. + +### Where the call goes relative to the work + +Record *after* the action has succeeded, or inside its transaction where one +exists — an action that rolls back must not leave an audit row. + +### Queued work logs intent, not outcome + +Server operations dispatch jobs (`SendPowerCommandJob`, `ConfigureVmJob`, …). +The audit log records what was **requested**, at the controller, where +attribution is unambiguous: "Eric requested a reinstall". Whether the job then +succeeded is deployment/task tracking, which already exists (the deployment +steps system; its design handoff lives in git history as +`docs/deployment-tracking-handoff.md`). Keeping that boundary stops the audit +log from becoming a second, worse job monitor. + +## Visibility + +Two orthogonal knobs, so neither question has to be answered per deployment +*and* per event: + +1. **Is this event ever client-visible?** — `AuditEvent::visibility()`, default + `Client`. This is a property of the event, decided once when it is added. +2. **Which staff member did it?** — `AuditSettings::$reveal_staff_identity` + (spatie settings, matching `app/Settings/BandwidthSettings.php`), default + `false`. Client-facing serialisation renders an admin actor who is not the + viewer as "Staff"; flipping it on names them. Admin-facing views always show + the real actor. + +Default posture is therefore: clients see *that* staff acted on their server, +not *who*. Internal or small deployments flip one switch in admin settings. + +The existing IP rule in `ActivityLogData` is worth carrying over — an actor sees +their own IP, admins see all, everyone else sees none. + +## Retention + +`PruneAuditLogsCommand`, daily, replacing the currently-broken `PruneCommand` +registration in `routes/console.php`: + +- `AuditRetention::FOREVER` events are never deleted. +- Everything else is deleted past `config('audit.prune_days')` (default 90, + under `APP_AUDIT_PRUNE_DAYS`, replacing `APP_ACTIVITY_PRUNE_DAYS`). +- Deletes chunk (`audit.prune_chunk`, default 1000) so a long-neglected install + does not issue one enormous statement. By explicit id list, because Postgres + has no `DELETE ... LIMIT`. + +This is a bespoke command rather than Laravel's generic `PruneCommand`, because a +`prunable()` scope cannot express a per-event exemption. + +## API and UI + +**Client** — `GET /api/client/servers/{server}/audit-logs`, behind the existing +server-access middleware, filtered through the model's +`clientVisible()` scope unless the viewer is an admin. Paginated, sortable by `created_at`. + +**Admin** — `GET /api/admin/audit-logs` via `spatie/laravel-query-builder`, +filterable by `event`, actor, subject, `batch` and date range. + +`ActivityLogData` is replaced by `AuditLogData` exposing `event` (the key), +`properties`, masked `actor`, conditional `ip`, and `createdAt`. + +Frontend: a new `resources/scripts/features/servers/activity/` tab, and +`resources/scripts/features/admin/audit-logs/` for the global table. The tab is +labelled "Activity" for users; everything in code is called `audit` — the route +names are not user-visible, so the internal vocabulary stays consistent. + +## The coverage test + +`tests/Feature/Audit/AuditCoverageTest.php` enumerates registered +`POST/PUT/PATCH/DELETE` routes in `api-client.php` and `api-admin.php` and +asserts each one's controller file references `AuditEvent::`, or appears in an +explicit `EXEMPT` map with a one-line reason per entry. + +Be honest about what this is: a **heuristic guard**, not a proof. It cannot tell +whether the right event fires on the right branch, only that somebody thought +about the endpoint. It exists so a new mutating route fails CI instead of +silently logging nothing, and the exemption list makes "we decided not to log +this" a deliberate, reviewable act. + +## Slices + +1. **Foundation** *(done)* — migration, `AuditEvent` + `AuditRetention` + `AuditVisibility`, + `AuditLog` model, `AuditLogger` + facade, `AuditSettings`, prune command, + fix the broken schedule, delete the old port (`app/Services/Activity/*`, + `app/Facades/{Activity,LogBatch,LogTarget}.php`, + `app/Models/ActivityLog{,Subject}.php`, `app/Http/Middleware/Activity/*`, + `app/Events/Activity/Activity.php`, `app/Data/Activity/*`, + `app/Providers/ActivityLogServiceProvider.php`, `config/activity.php` — + **not** the Proxmox task files listed above). +2. **Client + account call sites** *(done)* — server power, reinstall, rename, backups, + restore, disks, network, firewall, password reset, console; login, logout, + failed login, password change, 2FA and passkey changes, API key lifecycle, + session revocation, OAuth connections. +3. **Admin call sites and token attribution** *(done)* — nodes, locations, users, + presets, templates, IPAM, settings. +4. **Client server Activity tab.** *(done)* +5. **Global admin audit log.** *(done)* +6. **Coverage test and the exhaustive TS copy map.** *(done)* + +Slices 1-3 are shippable without any UI; 4 and 5 are what close #53. + +## What the build added beyond the plan + +- **Authentication is audited from events, not call sites.** Login, logout, + failed login and the two-factor transitions run through Fortify's own + controllers, so there is no code of ours to put a `Audit::record()` in. + `App\Listeners\AuditAuthenticationSubscriber` handles them. Its methods are + named `on*` rather than `handle*` on purpose: Laravel's event auto-discovery + claims any `handle*` method taking an event, which registered every listener a + second time on top of the explicit `Event::subscribe()` and logged every + sign-in twice. +- **`server.power.sent` carries the command as a property** rather than there + being a case per signal. `PowerCommand` has seven values and an admin mirror of + each; enumerating them would mean fourteen cases and a catalog change every + time it grows. +- **Three auth cases were dropped from the catalog** (`auth.login.passkey`, + `auth.two-factor.challenged`, `auth.identity.confirmed`). A passkey login, a + completed two-factor challenge and an identity re-confirmation all end in + `Auth::login()`, so each would have double-counted one sign-in. +- **The API layer** is `AuditLogData` plus `AuditActorData` / `AuditSubjectData`. + Actor masking lives in `AuditActorData::forViewer()`, which is also where the + `reveal_staff_identity` setting is read. +- **Coverage stands at 110 handlers**, deduplicated across `api/client`, + `api/admin`, `api/application` and `api/auth`. `api/application/*` is a + token-authenticated mirror of `api/admin/*` served by the **same controllers**, + so one call site covers both and the actor resolves to a `User` or a + `SystemActor` accordingly. A second test fails if an exemption stops matching + any route, so a stale entry cannot sit there quietly excusing a future + controller that reuses the name. diff --git a/docs/card-design.md b/docs/card-design.md new file mode 100644 index 00000000000..3688765a808 --- /dev/null +++ b/docs/card-design.md @@ -0,0 +1,483 @@ +# Card design + +How we build cards in the panel, and where the design comes from. Read this before +adding a new card-shaped surface (settings panels, create/edit forms, dashboard tiles) +so they stay consistent instead of each re-inventing padding, header layout, and footers. + +## Where this comes from + +Our card + form primitives are ported directly from **shadcn/ui's "create" (theme +customizer) page** — the gallery of demo cards shown at + (Environment Variables, Invite Team, Book Appointment, +Report Bug, Weekly Fitness Summary, …). We took the **`base` + `nova` style** values +specifically; some of our primitives carry a comment saying so (e.g. +`components/ui/Card/Card.tsx`, `components/ui/Field/Field.tsx`). + +### Upstream source paths + +Repo: [`shadcn-ui/ui`](https://github.com/shadcn-ui/ui), branch `main`. + +| What | Path | +| --- | --- | +| Customizer / "create" page (the app shell + control panel) | `apps/v4/app/(app)/(create)/` — `page.tsx` plus `components/*` (the pickers/customizer, **not** the demo cards) | +| **The demo cards in the gallery** | `apps/v4/registry/bases/base/blocks/preview/cards/*.tsx` | +| Preview assembler (lays the cards into the masonry grid) | `apps/v4/registry/bases/base/blocks/preview/index.tsx` | +| Card primitive | `apps/v4/registry/bases/base/ui/card.tsx` | +| Field primitive | `apps/v4/registry/bases/base/ui/field.tsx` | + +Good demo cards to read when building a **form inside a card** (our most common case): + +- `.../cards/report-bug.tsx` — title + description, `FieldGroup`, a two-column + `grid grid-cols-2 gap-3` row, textarea, and a footer with a right-aligned button pair. +- `.../cards/book-appointment.tsx` — `CardContent` as `flex flex-col gap-4` mixing a + `FieldGroup` with an `Alert`, footer with one full-width button. +- `.../cards/invite-team.tsx` — repeated rows, a `Separator` between sub-groups, and an + `InputGroup` with an inline copy button. + +> **Heads-up when reading upstream:** the `apps/v4/registry/bases/*` primitives express +> their styling through `cn-card`/`cn-*` CSS-layer utility classes, **not** inline +> Tailwind. We deliberately did **not** adopt that CSS-layer system — we kept the explicit +> Tailwind classes (the values match the `nova` base). So compare upstream *composition +> and structure*, and take our *class values* from our own primitives below. + +## Our primitives + +| Component | File | Base classes | +| --- | --- | --- | +| `Card` | `components/ui/Card/Card.tsx` | `flex flex-col rounded-xl bg-card text-sm text-card-foreground ring-1 ring-foreground/10` | +| `CardHeader` | `.../CardHeader.tsx` | `flex flex-col space-y-1 p-4` (switches to a `grid-cols-[1fr_auto]` layout when a `CardAction` child is present) | +| `CardTitle` | `.../CardTitle.tsx` | `text-base font-medium leading-snug` (renders `

`; override with `as`) | +| `CardDescription` | `.../CardDescription.tsx` | `text-sm text-muted-foreground` | +| `CardAction` | `.../CardAction.tsx` | top-right slot in the header; needs `CardHeader`'s grid mode | +| `CardContent` | `.../CardContent.tsx` | `p-4 pt-0` | +| `CardFooter` | `.../CardFooter.tsx` | `flex items-center border-t bg-muted/50 p-4` | +| `Field` / `FieldGroup` / `FieldLabel` / `FieldDescription` | `components/ui/Field/` | `FieldGroup` stacks fields with `gap-5`; `Field` supports `orientation="horizontal"`; a `FieldLabel` wrapping a `Field` becomes a **radio card** (see below) | +| `InputGroup*` | `components/ui/InputGroup/` | input with inline addons/buttons | +| `InputForm` / `CheckboxForm` | `components/ui/Forms/` | RHF-wired field + label + error, our default inside forms | + +### The radio card is already in `Field` + +A **`FieldLabel` whose direct child is a `Field`** is a selectable card, and none of it +needs writing at the call site: the label picks up `rounded-lg border` and gives the field +`p-2.5`, then `has-data-checked:border-primary/30 has-data-checked:bg-primary/5` +(`/20` and `/10` in dark) tints it once the control inside reports `data-checked`. + +```tsx + + + + + + {group.name} + {group.description} + + + +``` + +Two things to keep in mind. The `Field` has to be a **direct** child or none of the +`has-[>[data-slot=field]]:` selectors match. And the state attribute is Base UI's +`data-checked`, not Radix's `data-state=checked` — a ported Radix selector compiles fine +and silently never matches. + +Lay a set of them out with `grid-cols-[repeat(auto-fill,minmax(14rem,1fr))]` rather than a +`@md:` breakpoint when the same field renders at more than one width: the `@container` a +container query resolves against is `AppLayout`'s content area, not the card the cards are +sitting in (see the `@sm:`/`@md:` warning under *Do / don't*). + +The flat `ring-1 ring-foreground/10` (instead of `border` + `shadow`) is the defining look +of the `nova` base — cards read as quiet, inset surfaces rather than raised panels. + +`flex flex-col` is upstream's too. We dropped it originally because we swapped its `gap-6` +for per-part padding and the column looked incidental — it is not. A card in a grid row is +stretched to the height of the tallest card beside it, and a plain block card leaves that +extra height at the bottom: `CardContent` keeps its own height, so anything centred inside +it centres against the header rather than the card. That is what made every empty state on +`/security` sit high with dead space under it. **A card whose content should fill the +stretched height gives `CardContent` `flex-1`** — see the four `/security` cards, which pair +it with `grid min-h-[12rem] place-items-center` so the empty state has a floor when the card +is *not* the tall one. + +### Where we diverge from nova: field backgrounds + +Upstream ships `Input` / `Textarea` / `InputGroup` / the `Select` trigger as +**`bg-transparent`**. That works upstream because every field there sits inside a white +`Card`, so transparent *renders* white. We put forms on tinted surfaces too — the node +create page lays sectioned rows straight onto `AppLayout`'s `bg-muted/40` — and there a +transparent field has nothing white beneath it and reads as washed-out or disabled rather +than fillable. + +So **our field primitives use `bg-background`**. Two things make this safe rather than a +free-for-all: + +- **Inside a `Card` it is a no-op** — the card is already `bg-card`, so white-on-white is + identical to transparent. Nothing in the reference layout changes. +- **It mirrors what nova already does in dark mode.** The same primitives carry + `dark:bg-input/30`: on a dark surface the base *already* gives fields their own fill + instead of inheriting. We are applying that same intent to light mode. + +Corollaries: don't "fix" a field by adding `bg-background` at the call site (it's in the +primitive), and don't reach for `Button variant="outline"` as a field-like trigger and then +override its background — `outline` is `bg-background` for button reasons, which is only +coincidentally the same value. `InputGroupInput`/`InputGroupTextarea` stay `bg-transparent` +on purpose: the `InputGroup` shell owns the fill, and a second one would double up. + +### Status colour is a token, including the good kind + +`--destructive` always had a token and `--success` never did, so "this finished, and it +went well" got written as a literal `text-green-500` — one colour on the deployment screens +that no theme could reach and no dark-mode step ever touched. There is now a `--success` +token in both blocks of `app.css`, mapped in `tailwind.config.cjs` as `success`; use +`text-success` / `bg-success` (and `bg-success/40` for the rail between finished steps) the +way you already use `text-destructive`. Semantic colour is separate from the accent: blue +means "in progress", not "good". + +## Anatomy — the rules + +A card follows this order top-to-bottom. Skip parts, never reorder them. + +```tsx + + + Connection + Proxmox API endpoint & token. + {/* optional: {/* or a right-aligned pair */} + + +``` + +1. **Header is always title + one-line description.** Never a bare title. The description + says what the card is *for*, in the user's words, not the system's. +2. **Content groups fields with `FieldGroup`**, which owns vertical rhythm (`gap-5`) — do + not hand-space fields with `space-y-*`. Multi-column rows are `grid grid-cols-2 gap-3` + *inside* the group. +3. **Mixing a field group with a non-field block** (an `Alert`, a preview, a second group) + → give `CardContent` `className="flex flex-col gap-4"` and let each block sit as a + flex child. Separate two field sub-groups with ``. +4. **The primary action lives in `CardFooter`**, which is visually divided (`border-t + bg-muted/50`). Either a single **full-width** button (`className="w-full"`) or a + **right-aligned pair** (wrap in a `Field orientation="horizontal"` with `justify-end`, + secondary action as `variant="outline"` first, primary last). +5. **Header-level actions** (a "New", a menu) go in `CardAction`, not the footer. +6. **Radius/ring/padding come from the primitives.** Don't re-declare `rounded-*`, + `border`, `shadow`, or `p-*` on a `Card`/`CardContent` — override only for a deliberate + exception, and note why. + +## Do / don't + +- **Do** let a page be a grid of cards (`grid gap-4 @xl:grid-cols-2`), sizing a wide card + with `@xl:col-span-2`. See the reference layout cited under *In this codebase* below. +- **Do** keep body text at `text-sm` (the Card sets it) and descriptions + `text-muted-foreground`. +- **Do** match the checkbox to the card it sits in. In a **settings** card a switch row + (`justify-between`, `border-t` between rows) reads cleaner than a boxed one; in a card + where the user is **choosing** things — a picker, a wizard step — use the boxed + `CheckboxForm` (`rounded-lg border p-3`, checkbox + label + description), which is the + same shape as the radio cards above it. A bare checkbox row among selection cards reads + as a different design. The rebuild page's "Start the server when the install finishes" + is the boxed case; `/security`'s toggles are the row case. +- **Don't** stack sections with giant `space-y-16` gaps (the old create-node page). Card + padding + `FieldGroup` gaps already provide the rhythm. +- **Don't** read a `@sm:`/`@md:` in a card as a statement about *the card*. The + `@container` is almost always `AppLayout`'s content wrapper (`AppLayout.tsx:42`), so + these queries measure the **whole content area** — a card in a 4-col row is a quarter of + what its own `@md:` is testing. Worse, a card's width need not be monotonic in the page + width: if its `col-span` changes at a breakpoint it can get *narrower* as the page grows + (see the overview's Specifications card). Pick these thresholds by measuring the rendered + page, not by arithmetic, and put the measurement in the commit message. + +## In this codebase + +- **Reference layout:** `routes/_app/admin/servers.$serverId/settings.lazy.tsx` — Resources + / Backups as a responsive card grid, with Bandwidth spanning both columns beneath. + + This citation used to point at `nodes.$nodeId/settings.lazy.tsx`, which is a worse + example of the same pattern and is why the two were once read as contradicting each + other. Put two cards side by side only when they hold **comparable amounts of field**; + a grid row stretches every card to the tallest one, so pairing a two-field card with a + six-field card buys nothing but dead space in the short one. Node settings had exactly + that (General beside Connection) and now stacks full-width sections instead, letting + each card's own internal grid supply the horizontal density. Neither shape is more + correct than the other — the field counts decide. +- **A stack of cards that is a single task** — `routes/_app/servers.$serverUuid/rebuild.lazy.tsx` + plus `features/servers/components/client/Rebuild/*`: operating system, version, password, + in that order, with the destructive action in the last card's footer. Three things there + are worth copying. + + **Cap the form, not the page.** The wrapper around the heading *and* the cards is + `mx-auto w-full max-w-3xl`, the same move `nodes.$nodeId/settings.lazy.tsx:122` makes and + for the same reason: `AppLayout` gives the page up to 1600px, and a form stretched that + far pulls every label away from its control. Cap the page column instead and the + breadcrumbs come with it; leave out the `mx-auto` and the whole form hugs the left edge + under a full-width heading. + + **A card that fills its width beats a card with a measure inside it.** The first attempt + capped the field group at 26rem inside a full-width card, which just moved the emptiness + to the right of the inputs. Either the card is the width of its contents or the contents + are the width of the card. + + **A form spanning several cards still submits once.** The `
` wraps the card stack, + the submit lives in the last `CardFooter`, and it opens the confirmation rather than + firing the mutation — so the fields are validated before anyone is asked to type a server + name to confirm. +- **The two admin create screens are now the same screen twice.** Node + (`routes/_app/admin/_dashboard/nodes.create.lazy.tsx` + + `features/nodes/components/sections/*`) and server + (`routes/_app/admin/_dashboard/servers.create.lazy.tsx` + + `features/servers/components/admin/Create/sections/*`) both live in the app shell, + cap the column at `max-w-4xl`, open with the shared sticky `FormToolbar` + (`components/ui/FormToolbar`, carrying Cancel + submit), and stack `@container` + cards under it. Copy one when adding a third; do not reintroduce `FullscreenLayout`, + which no route uses any more. + + Inside a long card, split the fields into icon'd groups with the shared + `GroupHeader` (`components/ui/Forms`) rather than letting a run of number boxes blur + together — Processor and Memory on the node's capacity card. + +### A form should ask only what is authored + +The server create page was consistent with the node page and still hard to face: it put +24 controls on screen to collect the 8 answers that are actually written per server +(name, hostname, owner, node, storage, template group, template, password). The other 16 +are taken as they arrive — from the form's defaults, or from the preset that just filled +them in — so asking for them at full weight is what made the page read as busy. Measured +before and after: **2,376px → 1,414px, 24 visible controls → 9, 7 cards → 5.** + +Two devices did that, and both are worth reaching for on any long form: + +- **`FieldFold` (`components/ui/Forms`) states its values instead of asking for them.** + A collapsed row reads `2 vCPU · 2 GiB · 20 GiB · unmetered · no backups` with an Edit + beside it. Nothing is hidden — the answers are on screen, they have just stopped being + questions. Write the summary in the values themselves, never as a field count + ("5 settings" tells the reader nothing they can check). + + It opens itself in the two cases where a fold would otherwise lie: when a field inside + it is **dirty** (which is exactly what applying a preset does — `applyPresetSettings` + passes `shouldDirty`, and RHF marks a field dirty only when the value actually differs + from its default, so a preset's changes announce themselves and untouched groups stay + shut), and when a field inside it **failed validation**, including the server errors + `handleFormErrors` maps back after a rejected submit. A click always beats the dirty + rule, and never beats the error rule — a fold that swallows the message leaves a + submit that fails with nothing on screen to explain it. Everything in the group must + be listed in `fields`, or its error is what gets swallowed. + +- **A unit belongs to the value, not the question.** `InputForm`'s `suffix` puts `MiB` / + `MB/s` / `GiB` inside the field's trailing edge, so `Memory` replaces + `Memory (MiB)` *plus* a helper line. Note the wiring: `FormControl` goes around + `InputGroupInput`, not around `InputGroup` — it clones its child to inject the `id` and + aria, and on the wrapper those land on a `div`, leaving the label associated with + nothing (the bug still open against the node page's `MemoryAmountField`). + +The card count came down the same way: merge a card whose whole content is two pickers +(Placement) into the card it qualifies, and put a repeating list (extra disks) inside the +group it belongs to rather than giving it a header of its own to say it is empty. + +## A table in a card is a `CardTable` + +`components/ui/CardTable` is the list-of-records shape: **the card is the frame, and the +rows are the card's own**. Reach for it instead of hand-assembling `Table` inside a +`CardContent` — half a dozen cards had each derived the same details separately (unpadded +content, `pl-4`/`pr-4` on the edge cells, `[&_tr:last-child]:border-0`, +`hover:bg-transparent` on the header row), which is exactly how one card ends up with a +tinted header strip and a bordered inset while its neighbour has neither. + +```tsx +const columns: CardTableColumn
[] = [ + { key: 'address', header: 'Address', className: 'whitespace-nowrap', cell: a => }, + { key: 'gateway', header: 'Gateway', className: 'text-muted-foreground text-xs', cell: a => a.gateway }, +] + + {/* deliberate: the rows bleed to the card's edges */} + a.id} + columns={columns} + empty={} + footer={<>

5 of 7

} + /> +
+``` + +What it decides for you, and why: + +- **No inset and no fill.** A bordered box with a tinted header, inside a card that is + already a surface, is three boxes to hold two columns. The tint some tables have is a + local `[&_th]:bg-muted` override, not `TableHead` — don't copy it into a card. +- **Columns hug their content; exactly one takes the slack** (the last, or the one marked + `fill`). An auto table spreads four short values across the whole card and the row stops + reading as one record. A single-column table gets a spacer cell instead. +- **The header row appears only when a labelled column has a neighbour.** A lone column of + addresses under the word "Address" is a band that says nothing. +- **`footer`** is the muted strip that closes the table: facts on the left, a count on the + right. Use it for what every row would otherwise repeat — a gateway they all share — and + for "5 of 7" when the card shows a prefix of a longer list. That is the card idiom; + `CardFooter` is still where an *action* goes. +- **It scrolls rather than overhangs.** Machine values don't wrap, and four columns of them + outrun a phone-width card. + +A card shows a *prefix* of a list and links out (`CardAction`); scrolling a table inside a +card is the page-sized behaviour, and belongs on the page whose subject the list is — +`features/servers/networking/components/AddressList.tsx` (the tab) versus `AddressRows.tsx` +(the overview card) are the two halves of that split. + +Still to convert, each currently hand-rolling the same shape: `UserServersCard`, +`NodesCard`, `DevicesCard`, `StorageConsumerTable`, `StorageList`. + +## Statistic cards: a meter is not a footer + +`StatisticCard` (`features/servers/components/client/Overview/`) is the compact +number-and-label tile used across the server overview. Three rules, each learned from the +way the overview row looked before 2026-07-17: + +1. **A progress bar goes in the `meter` slot, not a `CardFooter`.** `CardFooter` is + `border-t bg-muted/50`, so a bar placed there is ruled off and tinted like an action + bar. Worse, the old card gave it `grow justify-end`, which in a stretched grid row pins + the bar to the card's bottom edge — metres away from the number it measures. `meter` + renders inside `CardContent`, directly under the value. +2. **Only render a meter when there is a real ratio.** A bar hard-coded to `0` because the + data is missing does not read as "unknown", it reads as "empty" — the storage card drew + an empty disk whenever the guest agent was down. No ratio, no bar. +3. **The value slot holds a number.** When the preferred figure is unavailable, fall back + to one you *do* have and say so in the muted subline (storage shows the disk limit from + the server record, sublined `Disk limit • guest agent offline`, plus a warning icon in + the title). The old card put the string `Usage unavailable` where the number goes, which + both broke the row's alignment and buried the limit it was already showing. + +The corollary for the row as a whole: **every card in a statistic row uses `StatisticCard`.** +System Specifications was a plain `Card` with a `text-base` `CardHeader` sitting between two +tiles with `text-xs` compact headers, so the row read as two different designs colliding. +A card that opts out of the shared shell will not line up with its neighbours, no matter how +the grid is tuned. + +## Boolean form fields must never be handed `undefined` + +`CheckboxForm`, `CheckboxItemForm` and `SwitchForm` all pass `field.value ?? false` to the +Base UI primitive. The `?? false` is load-bearing, not defensive noise. + +Base UI decides once, on the **first render**, whether a component is controlled, and +remembers that for the component's whole life (`useControlled.mjs`: +`const { current: isControlled } = React.useRef(controlled !== undefined)`). A form built +as `useForm({ resolver })` with **no `defaultValues`** yields `field.value === undefined` +on that first render, so the primitive latches *uncontrolled* and then ignores every value +it is given afterwards — including everything a later `form.reset(...)` supplies. + +This is worse than a stale display. The box renders from Base UI's own internal state, so +it starts unchecked no matter what the record says, and the first click toggles that +internal state `false → true` and reports `onCheckedChange(true)` — meaning a user who +clicks once to "turn the thing off" submits it **on**. It shipped in the node settings page, +where `verify_tls` was stuck on and could not be turned off through the UI at all; every +Proxmox call failed TLS verification and the node's live cards never loaded. + +It is silent in production: Base UI's controlled/uncontrolled warning is behind +`NODE_ENV !== 'production'`, and text inputs in the same form populate normally from +`reset()`, so the form looks like it works. + +Prefer giving `useForm` real `defaultValues` as well — but the `?? false` in the primitives +is what makes every consumer safe by default. + +## A clipped panel needs room for the focus ring + +`CollapsiblePanel` and `AccordionContent` animate their height, which requires +`overflow: hidden` — and that clips at the panel's padding edge, cropping the 3px +`focus-visible:ring-3` of any control sitting against it. The first field in an open +"Advanced" disclosure loses the left of its ring; the last one loses the bottom. + +This kept coming back because the bug lives in the primitive and only ever shows up at a +call site, so it gets patched locally (a stray `px-1` on somebody's form) and returns with +the next panel. **Both primitives now carry `clip-slack`** (`app.css`), which pads the clip +box by `0.25rem` and cancels the same amount in margin: the ring has somewhere to paint, +nothing moves, and a collapsed `h-0` panel still measures zero. Anything else that has to +clip a box containing focusable controls should use it too — don't re-solve this at the +call site. + +Not `overflow-clip-margin`, which is designed for exactly this but isn't old enough to rely +on; and not "drop the clip once open", which races the height transition and lets content +spill mid-animation. + +**Related trap, same shape:** `AlertDialogAction`/`AlertDialogCancel` used to paint +`buttonVariants()` on themselves. With `asChild` — which is how `ConfirmDialog` uses them — +Radix merges the *parent's* className last, so a `variant="destructive"` on the `Button` +inside was silently overridden and every destructive confirmation rendered primary-blue. +A wrapper that is not the button must not style like one. + +## Dialog family, Tabs, and Select + +These primitives use the same `base` + `nova` source as Card, but a few deliberate +local choices are easy to mistake for drift: + +- `DialogContent` keeps `sm:max-w-lg` rather than nova's `sm:max-w-sm`; our dialogs + routinely hold lists and forms. Its `p-4`, rounded popover, and flat ring still come + from nova, so consumers should not add their own shell padding, radius, or shadow. +- `DialogContent`'s grid is `grid-cols-[minmax(0,1fr)]`, not the implicit `auto` column. + A grid item's automatic minimum size is its min-content, so a track can never be + narrower than the longest unbreakable string inside it: one pasted SSH key sized the + column past `sm:max-w-lg` while the popup's own background stayed capped, and the + header, fields and footer rendered *outside* the popup they belong to. The + `minmax(0, …)` floor lets the column shrink so the content wraps instead. **Any long + opaque value — a key, token, or ID — needs this**; `max-w-*` alone does not contain it. +- Dialog enter/exit uses Base UI's `data-starting-style` / `data-ending-style` + transitions, not nova's `animate-in` transform keyframes. Nested dialogs also scale + and move their parent; a transform keyframe would compete for those same properties. +- Nested desktop dialogs stay centred. `DialogContent` measures each popup's unscaled + border-box height and publishes it through the dialog stack so the visible parent + ledge remains exactly `1rem` regardless of either dialog's content height. +- `ResponsiveDialog` resolves the `md` breakpoint synchronously and once at its root. + Mantine's default effect-time initial value briefly mounts a desktop Dialog as a + Drawer, then remounts the entire subtree. Do not change + `getInitialValueInEffect: false` or call the media query independently in each part. +- `TabsList` leaves Base UI's `activateOnFocus` at `false`: arrow keys move focus and + Enter/Space activates. Automatic activation can trigger side effects merely while a + keyboard user moves past a tab (the passkey tab starts a WebAuthn ceremony). +- `SelectContent` follows nova's native-select-like `alignItemWithTrigger=true`. Base UI + reports `data-side="none"` in that mode, and we intentionally disable its open/close + animation. Pass `false` only when the popup must behave as a menu below the trigger. +- Select row padding lives on `Select.List`, not only on nova's `SelectGroup`, because + every current consumer places `SelectItem` directly in the list. `SelectGroup` keeps + its own padding for future grouped content; do not nest both padded paths unchanged. + +For mobile composition, use `ResponsiveDialogBody` and `ResponsiveDialogFooter` rather +than branching classes at the call site. The Drawer owns no popup padding while the +desktop Dialog does; those shared parts already reconcile the difference. + +## Auth screens: stock nova, and why a register was not worth it + +The auth screens use the primitives exactly as they ship — default `CardTitle`, default +`FormLabel`, default `Input`, and the tinted `CardFooter` action band. Two attempts to +give them their own typographic voice were built and removed, and the reasons are worth +keeping so they are not tried a third time by accident. + +**An `Input variant="underline"`** — `border-b` instead of `border` — was designed against +a 316px mockup with placeholder text in every field. It failed at the size the app +actually renders: a 1px `border-input` rule stretched 480px under an *empty* field, 40px +below its label (`FormItem`'s `gap-2` plus the input's `h-8`), with no box to show where +the field began. It read as a blank line on a paper form. Do not reintroduce one without +first rendering it empty, at the real card width, in both themes. + +**A `FormLabel tone="mono"` and a `CardTitle size="display"`** followed the underline out. +Individually defensible; together they made a screen that no longer read as the same app, +which is the thing the frontend-consistency rule exists to prevent. A register is only +worth its upkeep if it earns a second screen, and this one never got there. + +What survived, because none of it is a style: the auth shell dropped `lg:w-[30rem]` and +stays at `sm:w-96` — the card holds two 32px fields and a button, so the extra 96px was +dead width under any design. The login footer holds two things (submit, passkey) rather +than the four it used to (submit, divider, passkey, every provider), which is what made +the tinted band taller than the fields above it. Providers moved above the fields, so an +account that signs in through one does not read past a form it can never submit. And the +login page no longer sets `text-3xl` on its title by hand. diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000000..529655be7bb --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,185 @@ +# Configuration + +Convoy is configured through environment variables. Everything has a default in +`config/` except the handful of values that are specific to your install, so a +working `.env` is short. + +- **`.env.example`** — the local development template. Copy it, fill in the + blanks, done. +- **`.env.docker.example`** — the production template used by the installer. +- **`.env.reference`** — every variable Convoy reads, with its default, in the + order they appear below. Reference material; not something to copy. + +A variable you do not set takes the default shown here. Setting a variable to +its default has no effect, so prefer leaving it out — a short `.env` is easier to +review than one where the meaningful lines are buried. + +## Required + +These have no useful default and must be set. + +| Variable | Notes | +| --- | --- | +| `APP_KEY` | 32 random bytes, base64 encoded. Generate with `php artisan key:generate`. Every process — web, queue worker, scheduler — must share the same value: it decrypts sessions and encrypted columns, so changing it invalidates both. | +| `APP_URL` | The URL customers reach the panel on, including the scheme. Password-reset links, SSO deep links and asset URLs are all built from it. | +| `DB_*` | Connection details for Postgres. | +| `REDIS_*` | Connection details for Redis. Not optional — see below. | + +### Redis is required + +Horizon, the cache and the session store all run on Redis, so there is no +configuration in which Convoy runs without it. Horizon in particular has no +database-backed mode: every Proxmox action is a queued job, and the queue is +Redis. Plan for it as part of the install rather than as an add-on. + +## Application + +| Variable | Default | Notes | +| --- | --- | --- | +| `APP_NAME` | `Convoy` | Shown in the UI and used as the default mail sender name. | +| `APP_ENV` | `production` | Anything other than `local` disables developer conveniences. | +| `APP_DEBUG` | `false` | Never `true` on an internet-facing install: the debug page renders configuration and stack traces to whoever triggered the error. | +| `APP_TIMEZONE` | `UTC` | | +| `APP_LOCALE` | `en` | | +| `TRUSTED_PROXIES` | unset | Comma-separated IPs/CIDRs of proxies whose forwarded client-IP headers Convoy may trust. | + +### Trusted proxies + +Leave `TRUSTED_PROXIES` unset when the panel faces the internet directly. When a +load balancer or CDN sits in front of it, set it to that proxy's address — +otherwise the audit log and the rate limiter both see the proxy as the client, +which means one address for every customer. + +Never use `*` on a public origin: it tells Convoy to believe whatever +`X-Forwarded-For` a request arrives with, which lets anyone forge their apparent +address and evade the rate limiter. + +### Maintenance mode + +| Variable | Default | Notes | +| --- | --- | --- | +| `APP_MAINTENANCE_DRIVER` | `file` | `file` or `cache`. | +| `APP_MAINTENANCE_STORE` | `redis` | Which cache store holds the flag when the driver is `cache`. | + +`file` records maintenance mode on local disk, so `artisan down` only marks down +the process that ran it. That is correct for a single-process install and wrong +for a containerised one, where the web, worker and scheduler are separate +processes — those should set `APP_MAINTENANCE_DRIVER=cache` so all three go down +together. + +Note that Convoy overrides Laravel's default for `APP_MAINTENANCE_STORE`. +Laravel points it at the `database` cache store, which reads a `cache` table +Convoy has no migration for; leaving it at the framework default and selecting +the `cache` driver makes every request fail with `relation "cache" does not +exist`. + +## Sessions + +| Variable | Default | Notes | +| --- | --- | --- | +| `SESSION_DRIVER` | `redis` | | +| `SESSION_LIFETIME` | `525600` | Minutes — one year. Laravel's own default of 120 signs operators out of the panel far more aggressively than the way it is actually used warrants. | + +## Logging + +| Variable | Default | Notes | +| --- | --- | --- | +| `LOG_CHANNEL` | `stack` | `stack` writes files under `storage/logs`, which is what a bare-metal install wants. Containers should use `stderr` so output lands in `docker logs`. | +| `LOG_LEVEL` | `debug` | `info` is a better production default; `debug` is noisy enough to matter on a busy panel. | + +## Mail + +Standard Laravel mailer settings: `MAIL_MAILER`, `MAIL_HOST`, `MAIL_PORT`, +`MAIL_USERNAME`, `MAIL_PASSWORD`, `MAIL_ENCRYPTION`, `MAIL_FROM_ADDRESS`, +`MAIL_FROM_NAME`. When `MAIL_MAILER=mailgun`, set `MAILGUN_DOMAIN` and +`MAILGUN_SECRET` (and `MAILGUN_ENDPOINT`, default `api.mailgun.net`, for the EU +region). + +## Queue dashboard + +| Variable | Default | Notes | +| --- | --- | --- | +| `HORIZON_DOMAIN` | unset | Serve Horizon from a dedicated subdomain. | +| `HORIZON_PATH` | `horizon` | Serve it from a different path. | + +## Settings cache + +| Variable | Default | Notes | +| --- | --- | --- | +| `SETTINGS_CACHE_ENABLED` | `true` | Caches resolved settings so reads do not hit the database. Invalidated automatically on save; leave enabled in production. | +| `SETTINGS_CACHE_MEMO` | `false` | Additionally memoize within a single request. Off by default because it makes settings written mid-request invisible to the rest of that request. | + +## Retention and pruning + +Consumed by the scheduled prune commands in `routes/console.php`. These only run +if the scheduler is running. + +| Variable | Default | Notes | +| --- | --- | --- | +| `APP_AUDIT_PRUNE_DAYS` | `90` | Days of audit log to keep. Security events (authentication, credential and token changes) are exempt and kept forever. | +| `BACKUP_PRUNE_AGE` | `360` | Days before a backup is eligible for pruning. | +| `DEPLOYMENT_RETENTION_PERIOD` | `90` | Days of deployment records to keep. | +| `DEPLOYMENT_STUCK_AGE` | `1440` | Minutes after which an in-progress deployment is treated as stuck. | + +## Rate limits + +| Variable | Default | Notes | +| --- | --- | --- | +| `BACKUP_THROTTLE_LIMIT` | `2` | Backups allowed per server... | +| `BACKUP_THROTTLE_PERIOD` | `600` | ...per this many seconds. | + +## Outbound HTTP + +Applied to calls out to Proxmox and Anchor. + +| Variable | Default | Notes | +| --- | --- | --- | +| `GUZZLE_CONNECT_TIMEOUT` | `5` | Seconds to establish a connection. | +| `GUZZLE_TIMEOUT` | `15` | Seconds for the whole request. Raise it if a hypervisor is slow to answer, but not far: a long timeout means a wedged node holds queue workers open instead of failing fast. | + +## Update checks + +| Variable | Default | Notes | +| --- | --- | --- | +| `UPDATE_CHECK_REPOSITORY` | `ConvoyPanel/panel` | The repository the admin dashboard checks for newer releases. | + +## Metrics (optional) + +| Variable | Default | Notes | +| --- | --- | --- | +| `VICTORIAMETRICS_URL` | unset | Endpoint backing the admin dashboard's metric history (deltas and sparklines). Leave unset to disable; the dashboard works without it. | + +## SSO deep links (optional) + +Minted via `POST /api/application/users/{user}/generate-sso-token`. + +| Variable | Default | Notes | +| --- | --- | --- | +| `SSO_LINK_TTL` | `60` | Signed-link lifetime, in seconds. | +| `SSO_AUDIT_CHANNEL` | `LOG_CHANNEL` | Log channel each consumed link is written to. | + +## OAuth / OIDC (optional) + +Convoy acts as the Relying Party — see `config/oauth.php`. A provider appears on +the login screen only when its `*_ENABLED` flag is true **and** its client id and +secret are both set. + +| Variable | Default | Notes | +| --- | --- | --- | +| `OAUTH_REGISTRATION` | `false` | Auto-create a non-admin user for an identity matching no existing account. | +| `OAUTH_LINK_BY_VERIFIED_EMAIL` | `true` | Link a provider identity to an existing account by verified email. | + +Per provider — `GOOGLE`, `GITHUB`, `GITLAB`: + +- `OAUTH__ENABLED` (default `false`) +- `OAUTH__CLIENT_ID` +- `OAUTH__CLIENT_SECRET` +- `OAUTH__REDIRECT_URI` (default `/api/auth/oauth//callback`) + +Generic OpenID Connect works against any standards-compliant IdP (Keycloak, +Authentik, Okta). Set `OAUTH_OIDC_BASE_URL` to the issuer and the endpoints are +read from its `/.well-known/openid-configuration`; `OAUTH_OIDC_AUTH_URL`, +`OAUTH_OIDC_TOKEN_URL` and `OAUTH_OIDC_USERINFO_URL` only need setting when +discovery is non-standard. `OAUTH_OIDC_LABEL` (default `OpenID Connect`) is the +login-button text and `OAUTH_OIDC_SCOPES` (default `profile,email`) is a comma +list; `openid` is always requested. diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 00000000000..0b8d76106ae --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,152 @@ +# Deployment + +Convoy is deployed as a container image. The supported install is a dedicated +host running Docker, with the panel, its queue worker, its scheduler and — +unless you bring your own — Postgres and Redis on it. + +Like VirtFusion and SolusVM, Convoy expects to be the only application on the +host. It binds ports 80 and 443 and assumes it owns them. + +## Install + +```bash +curl -fsSL https://install.convoypanel.com | sudo bash +``` + +The installer asks for the hostname customers will reach the panel on and an +email address for the first administrator, installs Docker if it is missing, +writes `/opt/convoy`, starts the stack, and prints a URL and a temporary +password. + +Non-interactively: + +```bash +curl -fsSL https://install.convoypanel.com | sudo bash -s -- \ + --domain panel.example.com --email you@example.com --yes +``` + +### Requirements + +- Debian 12/13, Ubuntu 22.04/24.04, AlmaLinux 9/10 or Rocky Linux 9/10 +- 2 GB RAM minimum, 4 GB recommended +- 20 GB disk +- Ports 80 and 443 free and reachable +- `x86_64` or `arm64` + +### TLS + +If the hostname you give the installer is a domain that resolves to the host, a +certificate is obtained automatically over ACME and renewed without further +action. Certificates are stored in a volume, so they survive upgrades. + +If you give it an IP address, the panel serves a self-signed certificate and +browsers will warn on first visit — certificate authorities do not issue for +bare IPs. Point a domain at the host and re-run with `--domain` to fix this. + +To terminate TLS somewhere else instead, set `CONVOY_AUTO_HTTPS=off` and put your +proxy in front, then set `TRUSTED_PROXIES` to its address (see +[configuration.md](configuration.md#trusted-proxies)) — otherwise every client +appears to Convoy as the proxy. + +## Day-to-day + +`convoyctl` wraps the underlying `docker compose` commands: + +``` +convoyctl ps status of every container +convoyctl logs web follow the panel's logs +convoyctl upgrade back up, pull new images, restart, verify +convoyctl backup dump the database to /opt/convoy/backups +convoyctl artisan run an Artisan command +convoyctl shell open a shell in the panel container +convoyctl horizon queue worker status +``` + +Nothing here is magic — if you know Docker, `cd /opt/convoy` and use +`docker compose` directly. + +## Upgrading + +```bash +convoyctl upgrade +``` + +This takes a database backup, pulls the new images, restarts the stack, and +waits for the panel to report healthy. Migrations run automatically when the web +container starts. + +To control exactly which version you run, pin `CONVOY_VERSION` in +`/opt/convoy/.env` to a release tag instead of `latest`, and change it when you +want to move. + +## What is actually running + +| Service | What it does | +| --- | --- | +| `web` | Serves the panel. FrankenPHP (Caddy + PHP in one process), which also terminates TLS. | +| `worker` | Horizon. Every Proxmox action is a queued job, so nothing works without this. | +| `scheduler` | `schedule:work`. Runs the entries in `routes/console.php`, including the per-minute node and Anchor liveness polls that drive the status indicators. | +| `postgres` | Bundled database. | +| `redis` | Bundled Redis, used for the queue, cache and sessions. | + +The first three are the same image with different commands. All application +configuration lives in `/opt/convoy/.env` and is read by all three. + +Convoy is a control plane: almost every request spends its time waiting on the +Proxmox API rather than on PHP. The web tier is therefore configured for +predictability rather than raw throughput, and running more `web` replicas is +rarely the answer to a slow panel — check the hypervisors first. + +## Using your own database and Redis + +Point `DB_*` and `REDIS_*` at your own hosts in `/opt/convoy/.env`, then edit +`/opt/convoy/compose.yml` and delete: + +- the `postgres` and `redis` services, +- the `depends_on:` block from `web`, `worker` and `scheduler`, +- the `postgres:` and `redis:` entries under `volumes:`. + +Then apply it: + +```bash +cd /opt/convoy +docker compose up -d --remove-orphans +``` + +The image is identical either way. Your edits to `compose.yml` survive upgrades, +which only pull new images — but they are yours to re-apply if a future release +changes the file. + +Note that `convoyctl backup` only handles the bundled database; with an external +one, back it up with your provider's tooling. + +## Backups + +`convoyctl backup` writes a gzipped `pg_dump` to `/opt/convoy/backups`. It is +run automatically before every upgrade. It is *not* run on a schedule — put it +in cron if you want that: + +``` +0 3 * * * /usr/local/bin/convoyctl backup >/dev/null +``` + +Volumes hold the database, Redis data, issued certificates and the contents of +`storage/`. `docker compose down` leaves all of them in place; `down -v` destroys +them. + +## Troubleshooting + +**The panel container will not start.** Its startup checks fail loudly and on +purpose. `convoyctl logs web` will name the problem — a missing `APP_KEY`, an +`APP_URL` still pointing at localhost, or a storage volume the container cannot +write to. + +**Everything looks fine but nothing happens when I act on a server.** The worker +is down. `convoyctl horizon` tells you; `convoyctl logs worker` tells you why. + +**Status indicators are stale.** The scheduler is down. `convoyctl logs +scheduler` should show `nodes:poll` and `anchors:poll` running each minute. + +**Certificate errors.** ACME needs port 80 reachable from the internet and a +domain that resolves to this host. `convoyctl logs web` includes Caddy's output, +which says precisely which of those failed. diff --git a/docs/development.md b/docs/development.md new file mode 100644 index 00000000000..19abf674940 --- /dev/null +++ b/docs/development.md @@ -0,0 +1,128 @@ +# Development + +Convoy runs locally on [ddev](https://ddev.readthedocs.io/) — Laravel 12, PHP 8.4, +Postgres 17, Node 22. ddev provisions the whole stack (web, database, redis) and +runs Horizon and the scheduler for you. + +## Prerequisites + +- Docker — [OrbStack](https://orbstack.dev/) (recommended on macOS) or Docker Desktop +- [ddev](https://ddev.readthedocs.io/en/stable/users/install/ddev-installation/) + +## Local development (ddev) + +### First-time setup + +```sh +ddev start # boot web + Postgres + redis +ddev composer install +ddev exec php artisan key:generate # only if APP_KEY is empty +ddev npm install +ddev exec php artisan migrate +``` + +The app is served at **https://convoy.ddev.site**. ddev supplies the database, +redis, and mail config (see `web_environment` in `.ddev/config.yaml`), so you +don't set DB credentials by hand. + +### Frontend / Vite + +```sh +ddev npm run dev # Vite dev server with HMR +ddev npm run build # production build +ddev npm run types:generate # regenerate TS types (typescript:transform + wayfinder) +ddev npm run tc # tsc type-check (no emit) +``` + +### Background workers + +Horizon (queues) and the scheduler run automatically as ddev web daemons — no +separate terminals needed. They're defined under `web_extra_daemons` in +`.ddev/config.yaml`. + +### Tests + +The suite uses `RefreshDatabase` against a **separate `db_test` Postgres +database** (auto-created by a `post-start` hook), so running tests never touches +your dev data. + +```sh +ddev exec php artisan test +ddev composer analyze # PHPStan static analysis +``` + +### Handy commands + +```sh +ddev exec php artisan # any artisan command +ddev ssh # shell inside the web container +ddev logs -s web # web/php/nginx logs +ddev snapshot # save current DB state +ddev snapshot restore # restore it (e.g. jump back to a stable baseline) +ddev restart | ddev poweroff +``` + +Tip: use `ddev snapshot` to save a stable database before churning it on a +feature branch, then `ddev snapshot restore` when you switch to a bug fix. + +## Sandboxed development (Docker Sandboxes / `sbx`) + +Run an agent against Convoy in a throwaway Linux microVM — its own Docker daemon, +database, and volumes, isolated from your host ddev. A mistake costs only `sbx rm`. +One committed kit (full details in [`.sbx/README.md`](../.sbx/README.md)): +`.sbx/dev` boots the ddev stack. + +### 1. Start it + +```sh +sbx run --kit .sbx/dev claude +``` + +Any agent works in place of `claude`. The first run installs ddev (slow once); +make later starts instant by saving a template: + +```sh +sbx template save convoy-dev +sbx run -t convoy-dev --kit .sbx/dev claude # install is now a no-op +``` + +### 2. Finish setup (run inside the sandbox) + +```sh +ddev composer install +ddev exec php artisan migrate +ddev exec php artisan test +``` + +### 3. (Optional) Seed a Proxmox node + +Add to your **gitignored `.env`**, then seed: + +```dotenv +PROXMOX_FQDN=10.0.0.10 # an address the sandbox can reach +PROXMOX_TOKEN_ID=root@pam!convoy +PROXMOX_TOKEN_SECRET=xxxxxxxx +# PROXMOX_PORT=8006 +# PROXMOX_VERIFY_TLS=false +``` + +```sh +ddev exec php artisan db:seed --class=DevNodeSeeder +``` + +`.env` is mounted in, so it's already there. **Use a scoped API token, not full +`root@pam`** — the sandbox protects your machine, not your hypervisor. + +### Reaching the Proxmox node + +The sandbox has no route to a private node on its own. If yours isn't publicly +reachable, arrange network access on the host side before `sbx run`, and set +`PROXMOX_FQDN` to an address the sandbox can actually reach. + +### Notes + +- Secrets stay in the gitignored `.env` (mounted in), never in the committed kit. +- The sandbox's ddev/database is isolated from your host ddev (separate Docker + daemon) — no volume conflicts. +- `vendor/` and `node_modules/` live in the mounted workspace, so installs inside + the sandbox also land in your host checkout. diff --git a/docs/docker-sandbox.md b/docs/docker-sandbox.md new file mode 100644 index 00000000000..4f548f2fe31 --- /dev/null +++ b/docs/docker-sandbox.md @@ -0,0 +1,182 @@ +# Working in the Docker Sandbox + +This repo is often developed inside a **Docker Sandbox** — an isolated, disposable VM (its own +kernel, not just a container) that an AI agent drives. These notes are **sandbox-specific**: they +describe environment quirks and freedoms that do **not** apply to a normal host or CI, so nothing +here should be baked into committed project config. + +## You may install and run whatever you need + +The sandbox is isolated and throwaway, so inside it you are **free to install and run any tooling** +needed to develop and test — system packages (`sudo apt-get …`), global npm/pip/uv packages, +browsers and drivers (e.g. Playwright + Chromium for visual checks), profilers, etc. You do **not** +need to ask before installing dev/test dependencies here, and such installs are **local to the +sandbox** — do not commit them to the repo (no new runtime deps in `composer.json` / `package.json` +just to satisfy a one-off local probe). + +## Keep sandbox web traffic off your **host's** dev services + +The sandbox reaches the network through an HTTP(S) proxy +(`HTTPS_PROXY=http://gateway.docker.internal:3128`). HTTP clients — `curl`, and crucially +**Playwright/Chromium** — hand the *hostname* to that proxy instead of consulting `/etc/hosts`, +and the proxy resolves it **on the host side**. So a request to `https://convoy.ddev.site` from +inside the sandbox does **not** hit the sandbox's own ddev on `127.0.0.1` — it lands on **your +host's** ddev and drives your real app. Symptoms this produced: headless-Chromium e2e logins +showing up as `Chrome on Linux` sessions in the *host* DB, `test@test.com`'s password appearing +to "change" (the tests reset it on your DB), and create/delete-node tests mutating real data — +all while the sandbox's own DB stayed empty (`select count(*) from session_records` = 0). Confirm +which app answers with `curl -sk https://convoy.ddev.site/ -o /dev/null -w '%{remote_ip}\n'`: +`127.0.0.1` is the sandbox; anything else is the proxy → your host. + +Defense in depth — the leak should be blocked at all three layers so no single miss re-opens it: + +1. **Proxy-bypass local dev TLDs** so the hostname resolves to the sandbox's own loopback. + Append to `/etc/sandbox-persistent.sh` (sandbox-local, sourced before every command, never + committed — do **not** put this in `.ddev/config.yaml`, which is shared with the host): + + ```bash + if [ -z "${SBX_DDEV_NOPROXY_DONE:-}" ]; then + export NO_PROXY="${NO_PROXY:+$NO_PROXY,}.ddev.site,ddev.site" + export no_proxy="$NO_PROXY" + export SBX_DDEV_NOPROXY_DONE=1 + fi + ``` + + Wiped on sandbox **recreate**, so re-apply it at the start of a fresh sandbox (verify with the + `remote_ip` curl above). + +2. **Deny `*.ddev.site` at the proxy** so that even if the bypass is missing (fresh sandbox) or a + tool ignores `NO_PROXY`, a proxied request to your host's ddev is *blocked* rather than + silently forwarded. Run from the **host** (the allow-side syntax is + `sbx policy allow network `; confirm the deny subcommand with `sbx policy --help`): + + ```bash + sbx policy deny network '*.ddev.site' + ``` + + Bypass **+** deny means the only reachable `*.ddev.site` is the sandbox's own loopback — the + deny is the backstop for the window before layer 1 is applied on a new sandbox. + +3. **Guard the e2e scripts.** Don't hand-roll this per session — the `dev` kit ships + `.sbx/dev/browser.mjs` and publishes it to `/opt/sbx-e2e/browser.mjs` on every start. It bypasses + the proxy for ddev hosts and refuses to launch unless the app answers from `127.0.0.1`: + + ```js + import { BASE, launch, newContext, login, capture } from '/opt/sbx-e2e/browser.mjs' + + const browser = await launch() // proxy-bypassed + preflighted + const ctx = await newContext(browser) // ignores the mkcert cert + const page = await login(ctx, { email: '…', password: '…' }) + const overflow = await capture(ctx, { url: '/admin/nodes', width: 768, path: '/tmp/nodes.png' }) + await browser.close() + ``` + + A test that can tell it's pointed at the host and stops is the last line of defense. + +Playwright itself lives in `/opt/sbx-e2e`, **not** the repo, and scripts reach it by importing the +helper's absolute path (Node resolves `playwright` by walking up from `/opt/sbx-e2e`). Never +`npm install playwright` in the project — that puts sandbox-only tooling in `package.json` and +`package-lock.json`. The version is pinned in the kit because the Chromium build id is tied to it; +a floating `playwright@latest` installed mid-session gives you `Executable doesn't exist at +…/chromium-`, and the fix is to use the pinned copy, not to re-download browsers. + +## `ddev start` fails: "Failed to add hosts entry … read-only file system" + +`/etc/hosts` is a read-only bind mount from the host, and `*.ddev.site` has no DNS answer reachable +from in here — so ddev's hostname step can neither resolve `convoy.ddev.site` nor add it, and +`ddev start` aborts. With no local app running it is very tempting to tunnel to the **host's** ddev +instead. Don't: that is exactly the leak the section above is about, dressed up as a fix. + +The `dev` kit handles it on every start by overmounting a writable copy, after which ddev registers +its own hostnames normally: + +```bash +tmp=$(mktemp); { cat /etc/hosts; echo '# sbx: writable hosts overmount'; } > "$tmp" +sudo install -m 0644 -o root -g root "$tmp" /var/lib/sbx-hosts +sudo mount --bind /var/lib/sbx-hosts /etc/hosts +``` + +Nothing is written to the workspace and the overmount dies with the sandbox, so this stays +sandbox-local. In a sandbox that predates the kit change, run it by hand, then `ddev start` and +confirm with the `remote_ip` curl above. + +## Host browser: "invalid certificate" on *every* `*.ddev.site` site + +`ddev start` signs the project certificate with the mkcert CA of the machine it runs on, and writes +it to `.ddev/traefik/certs/.crt` — **inside the workspace**, which the sandbox shares with +your checkout. A sandbox has its own throwaway mkcert CA (`mkcert agent@claude-`), so starting +ddev in here overwrites the host's certificate in the repo, and the next host-side `ddev start` +copies that file into `~/.ddev/traefik/certs` for the shared router. The Mac does not trust that CA, +so the browser rejects the site — and because one `ddev start` refreshes the router config for every +running project, a *different* project's sandbox can be what broke the one you are looking at. + +The `dev` kit prevents it on every start by overmounting a sandbox-local directory over the cert +directory, before `ddev start` runs: + +```bash +sudo install -d -m 0755 -o 1000 -g 1000 /var/lib/sbx-ddev-certs +sudo mount --bind /var/lib/sbx-ddev-certs "$WORKSPACE_DIR/.ddev/traefik/certs" +``` + +ddev in here then signs into that directory and the checkout is never written to. To repair a host +already poisoned by an older sandbox, run `ddev restart` in each affected project **on the Mac** and +confirm the issuer is yours: + +```bash +openssl x509 -in ~/.ddev/traefik/certs/.crt -noout -issuer # must not say agent@claude-… +``` + +## `php artisan tinker` segfaults (SIGSEGV / exit 139) — fix + +**Symptom:** `php artisan tinker` (especially the interactive REPL) intermittently dies with a +segfault instead of evaluating. + +**Why it happens:** Tinker is built on **PsySH**, which — when `ext-pcntl` is present (it is here) — +defaults to `usePcntl = true` and runs *each* evaluation inside a **forked child process** (its +"forking loop"), so a fatal in your code can't kill the session and per-eval timeouts can be +enforced. The crash is **not** `pcntl_fork()` failing (a tight loop of bare `pcntl_fork()` runs +cleanly here). It is that after the fork the child re-enters PHP's runtime — opcache/JIT-compiled +code, loaded-extension state, the readline/terminal handle — inside the sandbox's virtualized +kernel, and *that* fork-and-continue occasionally faults. It's the **same class of intermittent +SIGSEGV the sandbox shows for other fork/thread-heavy tools** (PHPStan's parallel workers, the +Vite/esbuild build) — an environment interaction with forking, **not** a Convoy or Laravel bug. + +**Fix (sandbox-local, uncommitted):** tell PsySH to evaluate in-process instead of forking, by +dropping a config in the web container's home. It is read from `~/.config/psysh/config.php` +automatically (no env var, no repo change), and it lives outside the project tree so it is never +committed: + +```bash +ddev exec bash -c 'mkdir -p ~/.config/psysh && cat > ~/.config/psysh/config.php < false]; +PHP' +``` + +Re-create it after a `ddev` container rebuild (the container home is ephemeral). **Do not** add this +to `.ddev/config.yaml`, a committed `.psysh.php`, or any other repo file — it is a sandbox +work-around, and real dev machines / CI want the default forking behaviour. + +**Tradeoff:** with `usePcntl = false` a fatal error in a tinker command ends the REPL session (no +forked isolation) and there is no per-eval timeout. Fine for scripted probes; mildly less forgiving +for long interactive sessions. + +**Quoting caveat (bites agents constantly):** most "tinker is broken" moments in this repo are +actually **shell-quoting** errors in a `ddev exec … --execute="…"` one-liner (nested quotes / +backslashes producing malformed PHP → a PHP parse error or exit 1, *not* a segfault). Prefer piping +a heredoc into `php artisan tinker`, or `--execute` with a payload free of nested quotes, and read +the error: a `ParseError` is your quoting, exit `139` is the real segfault. + +## Other intermittent SIGSEGVs — just retry + +The same environment instability sporadically hits `ddev npm run build`, `cache:clear`, and +PHPStan's parallel workers (across both PHP and Node, so it's not any one tool). There is **nothing +to fix in the repo** — forcing e.g. PHPStan serial in `phpstan.neon` would only penalise real CI for +a sandbox quirk. Mitigations: + +- **Re-run** the command; it usually succeeds within a couple of tries. +- Run PHPStan with `--debug` (serial) to dodge the parallel-worker crash: + `ddev exec ./vendor/bin/phpstan analyse --memory-limit=4G --debug`. +- Run the test suite as `ddev exec vendor/bin/pest` (or `ddev exec php artisan test`), **not** + `ddev artisan test` — the ddev global-command wrapper segfaults booting the runner here. + +A different sandbox session may not hit any of this at all. diff --git a/docs/frontend-overhaul-audit.md b/docs/frontend-overhaul-audit.md new file mode 100644 index 00000000000..1d2f6e64a99 --- /dev/null +++ b/docs/frontend-overhaul-audit.md @@ -0,0 +1,400 @@ +# Frontend Overhaul Audit + +Status: audited through 2026-07-15 against `next` after the base + nova rollout. The +shared Textarea, Select, Checkbox, DropdownMenu, Popover, Command/combobox, +DataTable toolbar, OTP, accessible icon actions, admin server Disks, DataTable +empty/filtered-empty states, shared Show all control, admin dashboard Nodes +card, IPAM mobile-row work, and app-wide collection-state/responsive sweeps +identified below have been completed. All tracked items are closed. + +⚠️ **Truncating inside `Item` needs two non-obvious overrides** (cost real time, +will recur on every row conversion). `ItemTitle` is a `w-fit` flex row, so +`truncate` on it never ellipsises — put the text in a `` +inside a `w-full min-w-0` title. `ItemDescription` defaults to `line-clamp-2` + +`text-balance`; `text-wrap` is a longhand of `white-space`, so `text-balance` +silently overrides `truncate`'s `nowrap` (you get `text-overflow: ellipsis` with +`white-space: normal` — it wraps and the ellipsis never shows). Use +`block truncate text-nowrap`. `text-nowrap` is in tailwind-merge's `text-wrap` +group, so it genuinely replaces `text-balance`; plain `truncate` does not. + +⚠️ **A title that is a `Link`/`Button` needs a third override** (found 2026-07-15 +while converting the IPAM tables; the same bug was already latent in admin +Servers, admin Nodes, node Servers, and node IPAM). `buttonVariants` is +`inline-flex shrink-0`, so putting `truncate` on the link itself does nothing +twice over: `shrink-0` stops it shrinking inside `ItemTitle`'s flex row, and +`text-overflow` never applies to a flex container's own children. The link +escapes the row and `ItemContent`'s `overflow-x-hidden` clips it mid-word with +no ellipsis — the page does not overflow, so it looks fine at a glance and only +a long name reveals it. Use: + +```tsx + + + {name} + + +``` + +Verify with a genuinely long value — the `nodes` seed data carries +`A node with a deliberately long display name for truncation` for this. + +This document tracks the remaining visual-system and screen-composition work in +the frontend overhaul. It is an implementation checklist, not a record of work +already completed. Historical detail belongs in Git history. + +The target remains the shadcn create-page default: base variant, nova style. The +canonical values already used by `Input`, `Button`, and `Card` are: + +- Controls: `h-8`, `rounded-lg`, no shadow, `ring-3` focus treatment. +- Cards: flat `ring-1 ring-foreground/10`, `rounded-xl`, standard 16px padding. +- Lists: shared `Item`/`ItemGroup`, using muted rows where appropriate. +- Layout: shared components, `gap-2`/`gap-4`, responsive desktop and mobile + representations, and contextual empty states. + +## Summary + +The overhaul is partially complete. The theme, primary input/button/card +primitives, sidebar, account Security page, and several list/table screens use +the new system. However, some shared controls still use the previous styling, +which makes every consumer look partially migrated. Several older collection +screens also retain bespoke layouts. + +The remaining work should be completed in this order: + +1. Finish shared form and menu primitives. +2. Normalize DataTable toolbar controls and action buttons. +3. Recompose the admin server Disks page. +4. Convert remaining bespoke collection screens. +5. Complete responsive/mobile coverage. +6. Move remaining Radix primitives to Base UI screen-by-screen with browser + interaction testing. + +## Reported inconsistencies + +### Textarea + +The SSH key dialog correctly uses `TextareaForm`, but the shared primitive at +`resources/scripts/components/ui/Textarea.tsx` still has the old control chrome: + +- `rounded-md` instead of `rounded-lg`. +- `shadow-xs` instead of no shadow. +- `px-3` instead of nova's `px-2.5` rhythm. +- `ring-1` instead of `ring-3 ring-ring/50`. +- Missing nova invalid, disabled, and dark-state treatments. + +Because this is a shared primitive, the mismatch also appears in IPAM, +templates, node network forms, and the server SSH-key paste dialog. + +### DataTable button sizes + +The Locations toolbar exposes an inconsistent size contract: + +- `DataTableViewOptions` requests `size="sm"` and then overrides it to `h-8`. +- `CreateLocationModal` uses the actual small button height, `h-7`. +- Both retain manual `mr-2` icon spacing even though `Button` now supplies its + own gap. + +This affects every DataTable toolbar with right-side actions, not only Locations. + +### Admin server Disks page + +`resources/scripts/features/servers/components/admin/detail/ServerDisksPanel.tsx` +predates the current collection patterns: + +- A bespoke page heading/action row uses a nonstandard `gap-3`. +- The page title `Disks` is followed by a second collection title, `Attached + disks`. +- An empty disk collection renders column headers and a blank body. +- The raw table has no mobile `Item` representation. +- Secondary-disk actions are full inline buttons rather than the standard + compact action menu. +- The Add disk icon retains obsolete `mr-2` spacing. +- The route has no `staticData.title` metadata. + +The page should use either the standard page-level collection/DataTable pattern +or a card-local `CardAction` pattern. It needs a contextual empty state with an +Add disk action and responsive rows. + +### Select and dropdown controls + +The API token screenshot is the shared Select, not a DropdownMenu. The Select +family remains on the previous visual system: + +- `SelectTrigger`: fixed `h-9`, `rounded-md`, shadow, and `ring-1`. +- `SelectContent`: old rounded/bordered popup treatment. +- `SelectItem`: old item radius, padding, and focus treatment. +- No shared `sm`/`default` size API. + +The actual `DropdownMenu` family was subsequently aligned with nova and given a +shared destructive item variant. + +## Priority 0: shared primitives + +### Textarea and form wrapper + +- [x] Match `Textarea` chrome to the canonical `Input` values. +- [x] Preserve multiline-specific behavior and an appropriate minimum height. +- [x] Add matching invalid, disabled, and dark-state treatment. +- [x] Make `TextareaForm` combine caller-provided `disabled` with form submission + state instead of overwriting it. +- [x] Browser-check the SSH key, IPAM, template, and network dialogs. Done + 2026-07-15 across all four (each now renders through the migrated + `ResponsiveDialog`): dialog opens, multiline entry works, radius 10px + (`rounded-lg`) and padding 10px (`px-2.5`), no console errors, and the + 390px drawer has no overflow. Resting `box-shadow` is `none`; it only + appears on focus because Tailwind implements `ring-3` AS a box-shadow — + measure unfocused or it reads as a false positive. + +### Select + +- [x] Align the default trigger with the nova control height, radius, padding, + shadow, focus, invalid, disabled, and dark states. +- [x] Add a size API rather than relying on one-off height overrides. +- [x] Retain `h-auto` for intentionally rich, multi-line selectors. +- [x] Update popup, viewport, scroll buttons, and items as one component family. +- [x] Browser-check keyboard navigation, typeahead, focus return, collision + handling, validation, and mobile dialogs. Done 2026-07-15 — and it found + two real bugs in Select-inside-a-dialog (Escape closed the whole dialog; + keyboard nav was dead because Radix's focus trap fought Base UI's portaled + popup). Both are fixed at the root by the Dialog/Drawer/Sheet migration to + Base UI; re-verified afterwards on the previously-broken `/admin/tokens`. + Plain-page selects: Enter opens, ArrowDown highlights, Escape closes, focus + returns to the trigger. +- [x] Migrate to Base UI during this work if its interaction contract can be + verified on the owning screens. + +### Checkbox, radio, and OTP + +- [x] Move Checkbox off the old primary border, shadow, and one-pixel focus ring. +- [x] Add nova invalid, disabled, dark-state, and hit-target treatment. +- [x] Make `CheckboxForm` and `CheckboxItemForm` preserve caller `disabled` state. +- [x] Update the dormant RadioGroup primitive before introducing new consumers. + Now Base UI, chrome mirroring the shared Checkbox (`border-input`, no + shadow, `ring-3` focus, invalid/disabled, `after:` hit target). Verified via + a throwaway route since it has no consumer to host it: `role=radiogroup`/ + `radio`, correct `aria-checked`, `data-checked`/`data-unchecked`, primary + fill when checked, click and ArrowDown roving. `@radix-ui/react-radio-group` + is uninstalled. +- [x] Align OTP slots with the current control dimensions and focus treatment. +- [x] Browser-check login authenticator entry and representative checkbox forms. + +### Menus, command inputs, and comboboxes + +- [x] Update DropdownMenu content and items to the current popup/item treatment. +- [x] Add a destructive menu-item variant and use it for delete/kill actions. +- [x] Normalize Command/combobox input heights; current consumers mix `h-9` and + `h-10` while standard controls use `h-8`. +- [x] Give `ResourceComboboxForm` normal `FormControl` IDs, `aria-invalid`, + description/error linkage, and combobox role/state semantics. +- [x] Replace duplicated bespoke Show all controls with the shared Button. + +## Priority 1: buttons and DataTable + +- [x] Define one toolbar action size contract and remove contradictory `size` plus + height overrides. +- [x] Remove stale `mr-2`/`ml-2` icon margins now that Button supplies `gap`. +- [x] Remove the loading spinner's built-in manual margin from `Button`. +- [x] Use `size="icon"` consistently for pagination and action controls. +- [x] Add accessible names to icon-only buttons. +- [x] Make `DataTableToolbar` wrap or reflow on narrow screens. +- [x] Distinguish an empty collection from a filtered no-results state. +- [x] Allow contextual empty copy and a primary onboarding/create action. + +Representative affected shared components: + +- `resources/scripts/components/ui/DataTable/DataTableViewOptions.tsx` +- `resources/scripts/components/ui/DataTable/DataTableFacetedFilter.tsx` +- `resources/scripts/components/ui/DataTable/DataTableColumnHeader.tsx` +- `resources/scripts/components/ui/DataTable/DataTablePagination.tsx` +- `resources/scripts/components/ui/DataTable/DataTableToolbar.tsx` +- `resources/scripts/components/ui/Table/Actions.tsx` + +## Priority 1: screen composition + +### Admin server Disks + +- [x] Adopt the standard page or card collection composition. +- [x] Add loading rows/skeletons that match the eventual layout. +- [x] Add a contextual empty state with Add disk as the primary action. +- [x] Replace inline row buttons with the standard action menu. +- [x] Add a mobile `Item` row representation. +- [x] Add route title metadata and normalize title casing. +- [x] Verify add, resize, remove, primary-disk restrictions, and empty/loading + states against a live seeded node. Verified 2026-07-15 on PVE 9.2.2: + stopped VM 9999 rendered its 8 GiB `scsi0` primary as Managed with no + mutation menu; the UI allocated a 1 GiB `scsi1`, grew it to 2 GiB, and + removed it. PVE then had no `unusedN` entry or secondary volume. A delayed + real index response showed three table-shaped skeleton rows, an intercepted + empty response showed the contextual Add disk state, and the primary-only + list rendered as an `Item` at 390 px with no horizontal overflow. + +### Remaining bespoke collections + +These are the clearest screens that still predate the documented Item/DataTable +patterns: + +- [x] Client My Servers: bespoke cards, no loading skeleton, and no empty state. +- [x] Admin Templates: bespoke cards and detached create/empty-state actions. +- [x] Node Network: bespoke cards and an empty CardHeader used as a spacing shim. +- [x] Node Storages: bespoke cards, detached actions, and spacing shims. +- [x] Server Boot Order: hand-built bordered list instead of Item/ItemGroup. +- [x] Server Addresses: raw desktop table and duplicated overflow handling. +- [x] Admin dashboard Nodes card: plain-text empty state, and hand-rolled divs for + the mobile rows. The desktop/mobile split itself is **intentional and stays** — + this line originally read as "convert the whole card to Item rows", which was + tried and reverted: the dense table is a deliberate part of the dashboard + redesign, and the meter is only legible because a column header (desktop) or + an explicit label (mobile) names it. Only the mobile rows moved to shared + `Item`/`ItemGroup`. Do not re-flag the split. + +### Server subpage consistency + +- [x] Replace residual `gap-5`/`gap-6` page spacing with the established responsive + `gap-2`/`gap-4` rhythm where no semantic exception exists. Server subpages + done; `Header`'s internal `gap-6` is component rhythm, not page spacing, and + was left alone. +- [x] Give Graphs a page-specific heading instead of reusing the Overview header. + Now `Resource usage`. Note this also drops the power Toolbar from Graphs + (it came bundled in Overview's `Header`), matching every other subpage. +- [x] Consolidate Backups heading/quota/list controls into the normal page rhythm. +- [x] Remove hardcoded backup quota presentation and wire the empty-state action. + The quota was fully mocked; it now reads real limits plus a new `backupSize` + total. The empty-state action needed a create dialog built from scratch -- + there was no create-backup UI anywhere. +- [x] Review Rebuild's isolated width and spacing model against sibling pages. + It was the last subpage with its own model: a `flex flex-col gap-y-6` + wrapper (which made the page one flex child, defeating AppLayout's + `gap-2`/`@md:gap-4`) plus a bespoke `max-w-xl`. Now on the shared + one-column-of-two grid — measured identical to a Security card. It was also + the only server subpage missing route `meta`. + +## Priority 2: responsive coverage + +`DataTable.mobileRow` is opt-in, so several tables still become horizontally +scrolling desktop tables on small screens. + +- [x] Global admin Servers. The mobile row carries its own selection checkbox — + the desktop selection column is not rendered below `@md`, so without it + bulk power actions are unreachable on mobile. +- [x] Global admin IPAM groups. +- [x] IPAM address-block list. +- [x] IPAM attached-nodes list. +- [x] Address list within a block. +- [x] Admin server Disks. +- [x] Server Addresses. + +Every converted page should be checked at desktop width and approximately 390px, +including long names, empty data, loading data, pagination, filters, and row +actions. + +## Priority 2: Base UI follow-through + +Progress, Separator, Tabs, Select, Checkbox, DropdownMenu, Popover, Toggle/ +ToggleGroup, and Collapsible already use `@base-ui/react`. The following +families remain intentionally deferred because their composition and DOM +contracts differ from Radix: + +- Dialogs and sheets. +- Menus, popovers, and tooltips. +- Selects and checkboxes. +- Scroll areas. +- `asChild` wrappers and triggers. + +Migrate these opportunistically with their owning screen. Do not perform a blind +package-level replacement. Each migration requires interaction tests for focus, +keyboard behavior, dismissal, nested portals, mobile behavior, and accessible +names/descriptions. + +⚠️ **Base UI's state attributes are not Radix's, and a wrong selector fails +silently** — Tailwind never errors on a class that matches nothing, so a ported +Radix selector compiles clean and simply never fires. Known mappings, each +verified against the rendered DOM (`@base-ui/react` 1.6.0): + +| Component | Radix | Base UI | +|-------------|----------------------|------------------------------------------------| +| Collapsible | `data-state=open` | trigger `data-panel-open` (absent when closed); panel `data-open`/`data-closed` | +| ToggleGroup | `data-horizontal` | `data-orientation="horizontal"` | + +The rule Base UI follows: its default state→attribute mapping emits a bare +`data-` only when the state value is boolean `true`, and stringifies +otherwise (some components override this with a custom mapping — check +`utils/*StateMapping` in the dist before assuming). **Verify against the DOM, +not a green build.** The remaining Radix consumer is `Accordion`; Base UI ships an +equivalent when its owning screen comes up. (`RadioGroup` is migrated; +`Radio` uses `data-checked`/`data-unchecked`.) + +The `Collapsible` primitive (`components/ui/Collapsible`) was added for the +backups Advanced disclosure. Prefer it over `Accordion` for a single disclosure — +it is Base UI, and it avoids adding a new Radix consumer. + +## Intentional exceptions + +Do not normalize these mechanically: + +- Rich OS, template, network, and storage selectors may need `h-auto`. +- Local array editors may use shared controls without React Hook Form wrappers. +- Specialized full-row navigation and account setting controls need not look like + ordinary buttons. +- Inline editors may intentionally use small submit buttons. +- Raw links/buttons using `buttonVariants` are acceptable when semantics require + a native element and accessibility behavior is preserved. + +## Separate product work + +The bandwidth controls frontend is not part of this visual cleanup. It remains a +separate product feature in `v5-next-handoff.md`: + +- Server-create speed cap. +- Existing-server limits and inheritance editor. +- Node overage override. +- Global BandwidthSettings administration. + +The optional workspace/account switcher and destructive-button strength are also +product/design decisions, not migration defects. + +## Definition of done + +- [x] Shared controls use one documented size, radius, focus, invalid, disabled, + and dark-state system. +- [x] No component requests one Button size and overrides it back to another. + Verified 2026-07-15: zero `size="sm"` + `h-*` override pairs remain. +- [x] Icons rely on Button gap rather than call-site margins. Verified + 2026-07-15: zero `mr-2`/`ml-2` icon margins at call sites. +- [x] Collection pages have loading, empty, populated, filtered-empty, and error + behavior where applicable. Exhaustively swept 2026-07-15: all 11 + `DataTable` consumers now pass initial query failures into a shared error + state with a retry action, and query-backed page/card collections use the + same state rather than treating a failure as perpetual loading or empty + data. Browser-verified at 390 px by forcing the admin Nodes request to 503 + through all four React Query attempts, then restoring it: the error state + replaced the skeletons and Try again recovered to 10 real rows with no + unexpected console errors. A live Storage check also caught and closed a + loading race: Templates, Network, Storages, and the nested template sheet + no longer expose create actions whose dialog owner would unmount when a + loading query resolved to the empty state. +- [x] Collection screens have deliberate mobile representations rather than + accidental horizontal overflow. Exhaustively swept 2026-07-15: every + `DataTable` consumer supplies `mobileRow`; the only raw table outside the + shared component is the admin dashboard Nodes card's documented, + intentional desktop-table/mobile-`Item` split. Remaining page/card + collections use the responsive `Item`/`OverflowItemGroup` patterns. The + forced-error/retry Nodes check had no page overflow at 390 px before or + after recovery. +- [x] Destructive actions are visually and semantically distinct (shared + `variant="destructive"`, 29 call sites; nova's soft tint per the + maintainer's decision). +- [x] Icon-only controls have accessible names. Verified 2026-07-15 in the real + DOM (not by grep) across /admin, /admin/nodes, /admin/ipam, /security and + /admin/servers: **zero** visible controls with neither text nor an + accessible name. +- [x] Base UI migrations retain keyboard, focus, portal, and dismissal behavior. + Proven on the hard case: a Select nested in a dialog (focus enters the + popup, ArrowDown highlights, Escape closes only the select, a 2nd Escape + closes the dialog), plus nested dialogs sharing ONE backdrop. +- [x] `ddev npm run tc` and `ddev npm run build` pass. ⚠️ Run `tc` FIRST — vite + does not typecheck, so build-before-tc can leave a bundle that contradicts + the source. +- [x] Flagship screens are browser-verified at desktop and mobile widths with no + unexpected console errors or horizontal page overflow. The final gap — the + admin server Disks tab — was verified against a live PVE 9.2.2 node on + 2026-07-15 at 1440 px and 390 px; see Priority 1 above. diff --git a/docs/node-status-plan.md b/docs/node-status-plan.md new file mode 100644 index 00000000000..59033483394 --- /dev/null +++ b/docs/node-status-plan.md @@ -0,0 +1,258 @@ +# Node status and monitoring — plan + +Covers GitHub #104 (node resource overview on the admin dashboard, plus +monitoring with email alerts) and the reachability/power indicators wanted on +the Nodes table and the server lists. Written 2026-07-17. + +Slices 1, 2, 4 and 5 are implemented. Slice 3 (email alerting) is deliberately +parked — the maintainer does not want it yet, reaffirmed 2026-08-17. + +**#104 therefore cannot be closed on slice 4 alone.** The issue asks for a +resource overview *and* an email when a check fails; the first half is shipped +and the second is a standing decision not to build. Say that when closing rather +than implying the request was met in full. + +## The problem + +Live state is read per row, one PVE call at a time: + +- `ProxmoxServerClient::getStatus()` → `/nodes/{node}/qemu/{server}/status/current`, + **once per server**. +- `NodeStatusController` → `/nodes/{node}/status`, **once per node**. + +A 20-row server list would therefore make 20 PVE calls per render. Worse, a node +that is *down* does not fail fast — it burns the full connect timeout, so the +page costs `timeout × N`. Polling per render was never going to work. + +## The lever: one call answers everything + +`GET /cluster/resources` returns every node, every guest **and** every datastore +in one response: `type`, `status`, `cpu`, `mem`, `maxmem`, `disk`, `maxdisk`, +`uptime`, `node`, `storage`, `shared`. + +Note `disk`/`maxdisk` change meaning with `type`: used/total bytes on a +`storage` row, the guest's root image on a `qemu` one. Same keys, different +question — read them only off the row type you meant. + +Measured against the dev node (`us-southeast-2`, PVE 9.2.2): + +``` +ONE call to /cluster/resources took 158ms and returned 3 rows + type=node node=us-southeast-2 id=node/us-southeast-2 status=online cpu=0.009 mem=1720381440/16766861312 +``` + +Each Convoy `Node` row is a PVE host with its own credentials, so this is **one +call per node, independent of how many servers it hosts**. The server list's +N+1 collapses to "number of distinct nodes", and node reachability arrives in +the same response as the resource figures #104 asks for. + +**Trap:** on a real PVE *cluster* this returns the other members' nodes and +guests too. Always filter by `Node::$name` (the PVE node name), or you will +attribute another host's VMs to the wrong Convoy node. + +## The principle: the read path never touches PVE + +A scheduled poller writes state; the API only reads what is already written. + +This is why the read path uses no `Cache::remember` around a PVE call. That +pattern (as `LiveStorageService` uses it, correctly, for a different job) only +moves the stall onto whoever draws the cache miss — and for an unreachable node +that request still eats the full timeout. A miss must render **unknown**, never +trigger a fetch. + +## Where state lives, and why it differs + +**Node reachability → columns on `nodes`.** Alerting needs a state machine, and +a cache is volatile: losing Redis would re-alert every node on the next tick. +Columns also make status sortable and filterable in the table for free. + +| Column | Purpose | +| --- | --- | +| `status` | `online` \| `unreachable` \| `unknown` (`NodeStatus`) | +| `status_code` | the `ConnectionErrorCode` when unreachable — *why*, not just *that* | +| `status_message` | the raw error, for the details disclosure | +| `last_seen_at` | last **successful** contact; drives staleness | +| `status_checked_at` | last attempt, successful or not | +| `consecutive_failures` | debounce counter for alerting (slice 3) | + +**Guest power state → cache, one key per node.** `node:{id}:vm-states`, a +vmid→status map (`GuestStateCache`). High-churn, non-critical, and one key per +node beats a row write per server every 30s. TTL is `Node::STATUS_TTL_MINUTES`, +matching the node status it was observed alongside — this originally said "≈ 2× +the poll interval"; see slice 2 below for why it changed. + +## Unknown is not stopped + +If the poller has not run recently, the UI says **unknown**. It must never +render a running VM as stopped because a cron did not fire — that is worse than +admitting ignorance, because someone will click Start on a machine that is +already up. `last_seen_at` plus the poll interval is what separates "we asked +and it is off" from "we have not asked lately". + +## Why not a ping test + +#104 proposes monitoring "via ping test". ICMP proves a NIC answered. It does +not prove Proxmox is running, the token is still valid, or the certificate is +trusted — the TLS bug fixed in `edfa75a5` would have sailed through a ping test +while every API call failed. A host that pings but answers `token_invalid` is +**down** as far as Convoy is concerned. + +So the check is the authenticated API call we already make, classified through +the `ConnectionErrorCode` the connection test and `NodeUnreachableException` +already share. One vocabulary for "why is this node unhappy", everywhere. + +## Slices + +**1 — reachability, written by a poller (DONE).** +`NodeStatus` enum, the columns above, `NodeStatusPollService`, `PollNodeStatusJob`, +and `nodes:poll` scheduled every minute. One queued job per node so a dead node's +timeout never serialises behind a healthy one. Nodes table shows the state with +the cause behind it. + +**2 — guest power state (DONE).** `GuestStateCache` (vmid→status per node), +written by the poll, read into `ServerData::$powerState` and rendered by +`PowerStateBadge` on the client server list, the admin server list, and a node's +own server list. + +Correcting this section's own claim of "same response, no new call": slice 1 +shipped against `/nodes/{node}/status`, which does not return guests, so slice 2 +had to **switch the poll to `/cluster/resources`** — the endpoint the lever above +always assumed. Reachability now means "that call answered". Adding it as a second +call was the alternative, and was rejected: a second endpoint is a second timeout +to sit through on exactly the nodes that are down. + +Two deviations from what this document specified, both deliberate: + +- **TTL is `Node::STATUS_TTL_MINUTES` (5), not "2× the poll interval" (2).** Both + facts come from one response, so they have to lapse together — a node still + reading `online` beside guests already `unknown` is an inconsistency a viewer + can only read as a bug. +- **A failed poll leaves the map alone** rather than clearing it. One failure is + not evidence a guest changed state; the map stands until it expires on its own. + +**3 — alerting (#104's second half).** Notify on the `online → unreachable` +transition only, debounced behind `consecutive_failures >= N` so a flap does not +page anyone, plus a recovery notice on the way back. Laravel notifications over +the existing mail config. + +**4 — dashboard overview (#104's first half) (DONE).** CPU/RAM/storage per node +on the admin dashboard (`NodesCard`), read from the poller's snapshot +(`NodeResourceSnapshotCache`) and never fetched on the read path. + +Storage covers **every datastore, not just the host's root filesystem** — #104 +asks about "the installed hard disks", plural. The figures come from the +`type=storage` rows of the same `/cluster/resources` response the poll already +makes, which were previously decoded and discarded, so this costs no extra call +and no extra timeout on a node that is down. Rows are filtered by `Node::$name` +(the cluster trap again — a shared store is reported once per node that mounts +it). + +The dashboard shows them **summed into one figure per node**, not a meter each. +A meter per store makes the cell grow without bound — a host with a dozen +datastores turns one table row into a dozen meters, on a card meant to be read +at a glance across a fleet. The per-store breakdown belongs on the node's own +Storages tab, where there is room for it. + +The sum is over raw bytes, not a mean of percentages: averaging would let a full +10 GiB scratch store weigh as heavily as a half-empty 20 TiB array. Stores PVE +could not read are **excluded from the sum** rather than counted as empty — an +unmounted export reports 0/0 and would quietly deflate everything around it — and +`unreadableDatastores` is how the card admits the total is incomplete. + +`$datastores` still carries the per-store breakdown (sorted fullest-first) even +though the dashboard no longer draws it; it is there for a future Storages tab +that reads the poller's snapshot instead of calling PVE per request the way +`LiveStorageService` still does. + +Two notes for whoever touches this next: + +- `NodeResourceSnapshotData::$datastores` is a `DataCollection`, not an array of + `Data`. A plain array picks up the `data` wrapper when serialised through the + response, so the JSON came out as `datastores.data[]` while the generated + TypeScript said `NodeDatastoreUsageData[]`. +- The snapshot cache key carries a `:v2` suffix. Cached `Data` objects are + unserialised without running the constructor, so adding a property leaves rows + written by the old shape uninitialised and they throw on first read. Bump the + suffix when the shape changes; the old rows then simply expire. + +**Node detail page.** `NodeStatusController` (`/nodes/{node}/status`) is the one +read path that still calls PVE per request, because `/cluster/resources` does not +carry the CPU model, kernel, boot mode or PVE version that page shows. It is +gated on the stored status: a node already recorded `unreachable` is not asked at +all (neither on mount nor on the 30s refetch), and the page renders the cause the +poller classified, behind a "Check anyway" button. `unknown` still fires — nobody +has asked yet, and one call for one node is a reasonable way to find out. + +**5 — the storage model (DONE, except the global list).** Everything on +`storages` was operator-declared and unchecked, so any of it could drift. The +poll now records what PVE says beside it — `pve_type`, `pve_shared`, +`pve_content` and capacity — from the `type=storage` rows of the +`/cluster/resources` response it already makes, so discovery costs no request and +no timeout on a node that is down. + +`pve_type` is the load-bearing one. It separates a thin backend, where committed +legitimately exceeds written bytes, from a thick one where the same gap is space +nobody can account for — and it identifies a Proxmox Backup Server datastore, +which needs **no model of its own**. PBS is an ordinary storage in PVE too +(`type: pbs`, `content: backup`, marked shared, reached entirely through PVE), and +its three apparent caveats are the general `content`, `thin` and `shared` +properties every other backend already needs. `Support\StorageBackends` owns the +thin list, shared by the cluster DTO and the Eloquent side so they cannot drift. + +The storages tab reads capacity live → recorded → unknown and says which, so an +unreachable node costs freshness rather than the whole panel. `untracked` is +*withheld* rather than clamped on thin and deduplicating backends: the old +`max(0, ...)` turned a negative into zero and presented "nothing unaccounted for" +as a finding when it was an artefact of arithmetic that does not apply there. + +**Clusters.** `nodes.cluster_name` comes from `/cluster/status`, asked only after +`/cluster/resources` has already succeeded — a second endpoint is a second +timeout on a node that is down, and a test asserts the call is never made on an +unreachable one. Null means standalone, which is PVE's own answer rather than a +gap. + +That is what makes shared storage expressible. A storage may now be attached to +several nodes, refused unless the nodes share a cluster (`storage.cfg` is +cluster-wide, so a storage id means nothing across clusters) and unless PVE +actually reports it on the target — taking the operator's word for it is the same +mistake as trusting a hand-set `shared` flag. Rows name the other nodes they +reach, because "shared" as a badge does not tell a reader that 20 TiB of free +Ceph on four nodes is 20 TiB in total. + +Four pivot writes were fixed first, all one bug: `storage_to_node` declares +`storage_id` as its primary key, so with two nodes there are two rows answering +to it. `update()`, `updateBackupOrder()`, `buildSortQuery()` and `destroy()` are +now all node-scoped, and `destroy()` detaches rather than deleting when others +still reach the pool. + +**The global storage list (DONE).** Storage is a top-level Provisioning item +beside IPAM, which is already both a global inventory and a node tab — the same +shape storage took once a pool could be attached to several nodes. The node tab +stays and keeps its own job: registering a host's disks, and answering whether +this host can take another server. + +`StorageInventoryController` makes **no PVE call at all**. The node-scoped list +can afford one live lookup because it is one node; a fleet page would make one +per node, and a single unreachable host would stall the whole list for a full +connect timeout. It reads the figures the poll already writes, and a test asserts +no stray HTTP. Storages no node reaches are omitted, matching what +`OverviewService::storage()` already counts as fleet capacity. + +**History.** Per-node CPU/RAM/disk over time should come from PVE's own RRD store +(`GET /nodes/{node}/rrddata`, the node-scoped sibling of what +`ProxmoxStatisticsClient` already calls for servers), *not* from per-node series +in VictoriaMetrics. PVE consolidates with `AVERAGE` server-side; `metrics:snapshot` +is hourly and fleet-wide, and hourly sampling of an instantaneous CPU reading is +noise rather than a trend. Not built. + +## Risks + +- **The scheduler must actually run.** `schedule:run` is already required for + bandwidth quotas, so this adds no new dependency — but if it is not running, + every node reads `unknown` forever. That is the honest failure, and it is why + `unknown` is a first-class state rather than a bug. +- **Many nodes.** One job per node keeps failures isolated and parallel, but a + large install wants the queue workers to keep up; the poll is idempotent and + `withoutOverlapping` prevents pile-up. +- **Poll interval vs timeout.** The per-node timeout must stay well under the + interval or a wholly-offline fleet will never finish a pass. diff --git a/docs/pve-api/endpoints.json b/docs/pve-api/endpoints.json new file mode 100644 index 00000000000..38d077e082a --- /dev/null +++ b/docs/pve-api/endpoints.json @@ -0,0 +1,127425 @@ +[ + { + "id": "GET /access", + "method": "GET", + "path": "/access", + "section": "access", + "summary": "index", + "description": "Directory index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access\naccess\nindex\nDirectory index." + }, + { + "id": "GET /access/acl", + "method": "GET", + "path": "/access/acl", + "section": "access", + "summary": "read_acl", + "description": "Get Access Control List (ACLs).", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "The returned list is restricted to objects where you have rights to modify permissions.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/acl\naccess\nread_acl\nGet Access Control List (ACLs)." + }, + { + "id": "PUT /access/acl", + "method": "PUT", + "path": "/access/acl", + "section": "access", + "summary": "update_acl", + "description": "Update Access Control List (add or remove permissions).", + "pathParameters": [], + "requestParameters": [ + { + "name": "path", + "type": "string", + "required": true, + "description": "Access control path" + }, + { + "name": "roles", + "type": "string", + "required": true, + "description": "List of roles.", + "format": "pve-roleid-list" + }, + { + "name": "delete", + "type": "boolean", + "required": false, + "description": "Remove permissions (instead of adding it)." + }, + { + "name": "groups", + "type": "string", + "required": false, + "description": "List of groups.", + "format": "pve-groupid-list" + }, + { + "name": "propagate", + "type": "boolean", + "required": false, + "description": "Allow to propagate (inherit) permissions.", + "default": 1 + }, + { + "name": "tokens", + "type": "string", + "required": false, + "description": "List of API tokens.", + "format": "pve-tokenid-list" + }, + { + "name": "users", + "type": "string", + "required": false, + "description": "List of users.", + "format": "pve-userid-list" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm-modify", + "{path}" + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/acl\naccess\nupdate_acl\nUpdate Access Control List (add or remove permissions).\npath string Access control path\nroles string List of roles.\ndelete boolean Remove permissions (instead of adding it).\ngroups string List of groups.\npropagate boolean Allow to propagate (inherit) permissions.\ntokens string List of API tokens.\nusers string List of users." + }, + { + "id": "GET /access/domains", + "method": "GET", + "path": "/access/domains", + "section": "access", + "summary": "index", + "description": "Authentication domain index.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + "user": "world" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/domains\naccess\nindex\nAuthentication domain index." + }, + { + "id": "POST /access/domains", + "method": "POST", + "path": "/access/domains", + "section": "access", + "summary": "create", + "description": "Add an authentication server.", + "pathParameters": [], + "requestParameters": [ + { + "name": "realm", + "type": "string", + "required": true, + "description": "Authentication domain ID", + "format": "pve-realm" + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Realm type.", + "enum": [ + "ad", + "ldap", + "openid", + "pam", + "pve" + ] + }, + { + "name": "acr-values", + "type": "string", + "required": false, + "description": "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request." + }, + { + "name": "audiences", + "type": "string", + "required": false, + "description": "A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'." + }, + { + "name": "autocreate", + "type": "boolean", + "required": false, + "description": "Automatically create users if they do not exist.", + "default": 0 + }, + { + "name": "base_dn", + "type": "string", + "required": false, + "description": "LDAP base domain name" + }, + { + "name": "bind_dn", + "type": "string", + "required": false, + "description": "LDAP bind domain name" + }, + { + "name": "capath", + "type": "string", + "required": false, + "description": "Path to the CA certificate store", + "default": "/etc/ssl/certs" + }, + { + "name": "case-sensitive", + "type": "boolean", + "required": false, + "description": "username is case-sensitive", + "default": 1 + }, + { + "name": "cert", + "type": "string", + "required": false, + "description": "Path to the client certificate" + }, + { + "name": "certkey", + "type": "string", + "required": false, + "description": "Path to the client certificate key" + }, + { + "name": "check-connection", + "type": "boolean", + "required": false, + "description": "Check bind connection to the server.", + "default": 0 + }, + { + "name": "client-id", + "type": "string", + "required": false, + "description": "OpenID Client ID" + }, + { + "name": "client-key", + "type": "string", + "required": false, + "description": "OpenID Client Key" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "default", + "type": "boolean", + "required": false, + "description": "Use this as default realm" + }, + { + "name": "domain", + "type": "string", + "required": false, + "description": "AD domain name" + }, + { + "name": "filter", + "type": "string", + "required": false, + "description": "LDAP filter for user sync." + }, + { + "name": "group_classes", + "type": "string", + "required": false, + "description": "The objectclasses for groups.", + "default": "groupOfNames, group, univentionGroup, ipausergroup", + "format": "ldap-simple-attr-list" + }, + { + "name": "group_dn", + "type": "string", + "required": false, + "description": "LDAP base domain name for group sync. If not set, the base_dn will be used." + }, + { + "name": "group_filter", + "type": "string", + "required": false, + "description": "LDAP filter for group sync." + }, + { + "name": "group_name_attr", + "type": "string", + "required": false, + "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" + }, + { + "name": "groups-autocreate", + "type": "boolean", + "required": false, + "description": "Automatically create groups if they do not exist.", + "default": 0 + }, + { + "name": "groups-claim", + "type": "string", + "required": false, + "description": "OpenID claim used to retrieve groups with." + }, + { + "name": "groups-overwrite", + "type": "boolean", + "required": false, + "description": "All groups will be overwritten for the user on login.", + "default": 0 + }, + { + "name": "issuer-url", + "type": "string", + "required": false, + "description": "OpenID Issuer Url" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "LDAP protocol mode.", + "enum": [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "default": "ldap" + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'." + }, + { + "name": "port", + "type": "integer", + "required": false, + "description": "Server port.", + "minimum": 1, + "maximum": 65535 + }, + { + "name": "prompt", + "type": "string", + "required": false, + "description": "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent." + }, + { + "name": "query-userinfo", + "type": "boolean", + "required": false, + "description": "Enables querying the userinfo endpoint for claims values.", + "default": 1 + }, + { + "name": "scopes", + "type": "string", + "required": false, + "description": "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "default": "email profile" + }, + { + "name": "secure", + "type": "boolean", + "required": false, + "description": "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead." + }, + { + "name": "server1", + "type": "string", + "required": false, + "description": "Server IP address (or DNS name)", + "format": "address" + }, + { + "name": "server2", + "type": "string", + "required": false, + "description": "Fallback Server IP address (or DNS name)", + "format": "address" + }, + { + "name": "sslversion", + "type": "string", + "required": false, + "description": "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum": [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ] + }, + { + "name": "sync_attributes", + "type": "string", + "required": false, + "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." + }, + { + "name": "sync-defaults-options", + "type": "string", + "required": false, + "description": "The default options for behavior of synchronizations.", + "format": "realm-sync-options" + }, + { + "name": "tfa", + "type": "string", + "required": false, + "description": "Use Two-factor authentication.", + "format": "pve-tfa-config" + }, + { + "name": "user_attr", + "type": "string", + "required": false, + "description": "LDAP user attribute name" + }, + { + "name": "user_classes", + "type": "string", + "required": false, + "description": "The objectclasses for users.", + "default": "inetorgperson, posixaccount, person, user", + "format": "ldap-simple-attr-list" + }, + { + "name": "username-claim", + "type": "string", + "required": false, + "description": "OpenID claim used to generate the unique username." + }, + { + "name": "verify", + "type": "boolean", + "required": false, + "description": "Verify the server's SSL certificate", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/domains\naccess\ncreate\nAdd an authentication server.\nrealm string Authentication domain ID\ntype string Realm type. ad ldap openid pam pve\nacr-values string Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.\naudiences string A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.\nautocreate boolean Automatically create users if they do not exist.\nbase_dn string LDAP base domain name\nbind_dn string LDAP bind domain name\ncapath string Path to the CA certificate store\ncase-sensitive boolean username is case-sensitive\ncert string Path to the client certificate\ncertkey string Path to the client certificate key\ncheck-connection boolean Check bind connection to the server.\nclient-id string OpenID Client ID\nclient-key string OpenID Client Key\ncomment string Description.\ndefault boolean Use this as default realm\ndomain string AD domain name\nfilter string LDAP filter for user sync.\ngroup_classes string The objectclasses for groups.\ngroup_dn string LDAP base domain name for group sync. If not set, the base_dn will be used.\ngroup_filter string LDAP filter for group sync.\ngroup_name_attr string LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.\ngroups-autocreate boolean Automatically create groups if they do not exist.\ngroups-claim string OpenID claim used to retrieve groups with.\ngroups-overwrite boolean All groups will be overwritten for the user on login.\nissuer-url string OpenID Issuer Url\nmode string LDAP protocol mode. ldap ldaps ldap+starttls\npassword string LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.\nport integer Server port.\nprompt string Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.\nquery-userinfo boolean Enables querying the userinfo endpoint for claims values.\nscopes string Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.\nsecure boolean Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.\nserver1 string Server IP address (or DNS name)\nserver2 string Fallback Server IP address (or DNS name)\nsslversion string LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! tlsv1 tlsv1_1 tlsv1_2 tlsv1_3\nsync_attributes string 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.\nsync-defaults-options string The default options for behavior of synchronizations.\ntfa string Use Two-factor authentication.\nuser_attr string LDAP user attribute name\nuser_classes string The objectclasses for users.\nusername-claim string OpenID claim used to generate the unique username.\nverify boolean Verify the server's SSL certificate" + }, + { + "id": "DELETE /access/domains/{realm}", + "method": "DELETE", + "path": "/access/domains/{realm}", + "section": "access", + "summary": "delete", + "description": "Delete an authentication server.", + "pathParameters": [ + { + "name": "realm", + "type": "string", + "required": true, + "description": "Authentication domain ID", + "format": "pve-realm" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/access/domains/{realm}\naccess\ndelete\nDelete an authentication server.\nrealm string Authentication domain ID" + }, + { + "id": "GET /access/domains/{realm}", + "method": "GET", + "path": "/access/domains/{realm}", + "section": "access", + "summary": "read", + "description": "Get auth server configuration.", + "pathParameters": [ + { + "name": "realm", + "type": "string", + "required": true, + "description": "Authentication domain ID", + "format": "pve-realm" + } + ], + "requestParameters": [], + "returns": {}, + "permissions": { + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate", + "Sys.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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": {} + }, + "searchText": "GET\n/access/domains/{realm}\naccess\nread\nGet auth server configuration.\nrealm string Authentication domain ID" + }, + { + "id": "PUT /access/domains/{realm}", + "method": "PUT", + "path": "/access/domains/{realm}", + "section": "access", + "summary": "update", + "description": "Update authentication server settings.", + "pathParameters": [ + { + "name": "realm", + "type": "string", + "required": true, + "description": "Authentication domain ID", + "format": "pve-realm" + } + ], + "requestParameters": [ + { + "name": "acr-values", + "type": "string", + "required": false, + "description": "Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request." + }, + { + "name": "audiences", + "type": "string", + "required": false, + "description": "A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'." + }, + { + "name": "autocreate", + "type": "boolean", + "required": false, + "description": "Automatically create users if they do not exist.", + "default": 0 + }, + { + "name": "base_dn", + "type": "string", + "required": false, + "description": "LDAP base domain name" + }, + { + "name": "bind_dn", + "type": "string", + "required": false, + "description": "LDAP bind domain name" + }, + { + "name": "capath", + "type": "string", + "required": false, + "description": "Path to the CA certificate store", + "default": "/etc/ssl/certs" + }, + { + "name": "case-sensitive", + "type": "boolean", + "required": false, + "description": "username is case-sensitive", + "default": 1 + }, + { + "name": "cert", + "type": "string", + "required": false, + "description": "Path to the client certificate" + }, + { + "name": "certkey", + "type": "string", + "required": false, + "description": "Path to the client certificate key" + }, + { + "name": "check-connection", + "type": "boolean", + "required": false, + "description": "Check bind connection to the server.", + "default": 0 + }, + { + "name": "client-id", + "type": "string", + "required": false, + "description": "OpenID Client ID" + }, + { + "name": "client-key", + "type": "string", + "required": false, + "description": "OpenID Client Key" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "default", + "type": "boolean", + "required": false, + "description": "Use this as default realm" + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "domain", + "type": "string", + "required": false, + "description": "AD domain name" + }, + { + "name": "filter", + "type": "string", + "required": false, + "description": "LDAP filter for user sync." + }, + { + "name": "group_classes", + "type": "string", + "required": false, + "description": "The objectclasses for groups.", + "default": "groupOfNames, group, univentionGroup, ipausergroup", + "format": "ldap-simple-attr-list" + }, + { + "name": "group_dn", + "type": "string", + "required": false, + "description": "LDAP base domain name for group sync. If not set, the base_dn will be used." + }, + { + "name": "group_filter", + "type": "string", + "required": false, + "description": "LDAP filter for group sync." + }, + { + "name": "group_name_attr", + "type": "string", + "required": false, + "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" + }, + { + "name": "groups-autocreate", + "type": "boolean", + "required": false, + "description": "Automatically create groups if they do not exist.", + "default": 0 + }, + { + "name": "groups-claim", + "type": "string", + "required": false, + "description": "OpenID claim used to retrieve groups with." + }, + { + "name": "groups-overwrite", + "type": "boolean", + "required": false, + "description": "All groups will be overwritten for the user on login.", + "default": 0 + }, + { + "name": "issuer-url", + "type": "string", + "required": false, + "description": "OpenID Issuer Url" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "LDAP protocol mode.", + "enum": [ + "ldap", + "ldaps", + "ldap+starttls" + ], + "default": "ldap" + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'." + }, + { + "name": "port", + "type": "integer", + "required": false, + "description": "Server port.", + "minimum": 1, + "maximum": 65535 + }, + { + "name": "prompt", + "type": "string", + "required": false, + "description": "Specifies whether the Authorization Server prompts the End-User for reauthentication and consent." + }, + { + "name": "query-userinfo", + "type": "boolean", + "required": false, + "description": "Enables querying the userinfo endpoint for claims values.", + "default": 1 + }, + { + "name": "scopes", + "type": "string", + "required": false, + "description": "Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.", + "default": "email profile" + }, + { + "name": "secure", + "type": "boolean", + "required": false, + "description": "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead." + }, + { + "name": "server1", + "type": "string", + "required": false, + "description": "Server IP address (or DNS name)", + "format": "address" + }, + { + "name": "server2", + "type": "string", + "required": false, + "description": "Fallback Server IP address (or DNS name)", + "format": "address" + }, + { + "name": "sslversion", + "type": "string", + "required": false, + "description": "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!", + "enum": [ + "tlsv1", + "tlsv1_1", + "tlsv1_2", + "tlsv1_3" + ] + }, + { + "name": "sync_attributes", + "type": "string", + "required": false, + "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." + }, + { + "name": "sync-defaults-options", + "type": "string", + "required": false, + "description": "The default options for behavior of synchronizations.", + "format": "realm-sync-options" + }, + { + "name": "tfa", + "type": "string", + "required": false, + "description": "Use Two-factor authentication.", + "format": "pve-tfa-config" + }, + { + "name": "user_attr", + "type": "string", + "required": false, + "description": "LDAP user attribute name" + }, + { + "name": "user_classes", + "type": "string", + "required": false, + "description": "The objectclasses for users.", + "default": "inetorgperson, posixaccount, person, user", + "format": "ldap-simple-attr-list" + }, + { + "name": "verify", + "type": "boolean", + "required": false, + "description": "Verify the server's SSL certificate", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/domains/{realm}\naccess\nupdate\nUpdate authentication server settings.\nrealm string Authentication domain ID\nacr-values string Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.\naudiences string A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.\nautocreate boolean Automatically create users if they do not exist.\nbase_dn string LDAP base domain name\nbind_dn string LDAP bind domain name\ncapath string Path to the CA certificate store\ncase-sensitive boolean username is case-sensitive\ncert string Path to the client certificate\ncertkey string Path to the client certificate key\ncheck-connection boolean Check bind connection to the server.\nclient-id string OpenID Client ID\nclient-key string OpenID Client Key\ncomment string Description.\ndefault boolean Use this as default realm\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndomain string AD domain name\nfilter string LDAP filter for user sync.\ngroup_classes string The objectclasses for groups.\ngroup_dn string LDAP base domain name for group sync. If not set, the base_dn will be used.\ngroup_filter string LDAP filter for group sync.\ngroup_name_attr string LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.\ngroups-autocreate boolean Automatically create groups if they do not exist.\ngroups-claim string OpenID claim used to retrieve groups with.\ngroups-overwrite boolean All groups will be overwritten for the user on login.\nissuer-url string OpenID Issuer Url\nmode string LDAP protocol mode. ldap ldaps ldap+starttls\npassword string LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.\nport integer Server port.\nprompt string Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.\nquery-userinfo boolean Enables querying the userinfo endpoint for claims values.\nscopes string Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.\nsecure boolean Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.\nserver1 string Server IP address (or DNS name)\nserver2 string Fallback Server IP address (or DNS name)\nsslversion string LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! tlsv1 tlsv1_1 tlsv1_2 tlsv1_3\nsync_attributes string 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.\nsync-defaults-options string The default options for behavior of synchronizations.\ntfa string Use Two-factor authentication.\nuser_attr string LDAP user attribute name\nuser_classes string The objectclasses for users.\nverify boolean Verify the server's SSL certificate" + }, + { + "id": "POST /access/domains/{realm}/sync", + "method": "POST", + "path": "/access/domains/{realm}/sync", + "section": "access", + "summary": "sync", + "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.", + "pathParameters": [ + { + "name": "realm", + "type": "string", + "required": true, + "description": "Authentication domain ID", + "format": "pve-realm" + } + ], + "requestParameters": [ + { + "name": "enable-new", + "type": "boolean", + "required": true, + "description": "Enable newly synced users immediately.", + "default": "1" + }, + { + "name": "full", + "type": "boolean", + "required": true, + "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." + }, + { + "name": "purge", + "type": "boolean", + "required": true, + "description": "DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync." + }, + { + "name": "remove-vanished", + "type": "string", + "required": true, + "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).", + "default": "none" + }, + { + "name": "scope", + "type": "string", + "required": true, + "description": "Select what to sync.", + "enum": [ + "users", + "groups", + "both" + ] + }, + { + "name": "dry-run", + "type": "boolean", + "required": false, + "description": "If set, does not write anything.", + "default": 0 + } + ], + "returns": { + "description": "Worker Task-UPID", + "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/'." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/domains/{realm}/sync\naccess\nsync\nSyncs 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.\nrealm string Authentication domain ID\nenable-new boolean Enable newly synced users immediately.\nfull boolean 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.\npurge boolean DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.\nremove-vanished string 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).\nscope string Select what to sync. users groups both\ndry-run boolean If set, does not write anything." + }, + { + "id": "GET /access/groups", + "method": "GET", + "path": "/access/groups", + "section": "access", + "summary": "index", + "description": "Group index.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/groups\naccess\nindex\nGroup index." + }, + { + "id": "POST /access/groups", + "method": "POST", + "path": "/access/groups", + "section": "access", + "summary": "create_group", + "description": "Create new group.", + "pathParameters": [], + "requestParameters": [ + { + "name": "groupid", + "type": "string", + "required": true, + "format": "pve-groupid" + }, + { + "name": "comment", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/groups\naccess\ncreate_group\nCreate new group.\ngroupid string\ncomment string" + }, + { + "id": "DELETE /access/groups/{groupid}", + "method": "DELETE", + "path": "/access/groups/{groupid}", + "section": "access", + "summary": "delete_group", + "description": "Delete group.", + "pathParameters": [ + { + "name": "groupid", + "type": "string", + "required": true, + "format": "pve-groupid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/access/groups/{groupid}\naccess\ndelete_group\nDelete group.\ngroupid string" + }, + { + "id": "GET /access/groups/{groupid}", + "method": "GET", + "path": "/access/groups/{groupid}", + "section": "access", + "summary": "read_group", + "description": "Get group configuration.", + "pathParameters": [ + { + "name": "groupid", + "type": "string", + "required": true, + "format": "pve-groupid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/access/groups", + [ + "Sys.Audit", + "Group.Allocate" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/groups/{groupid}\naccess\nread_group\nGet group configuration.\ngroupid string" + }, + { + "id": "PUT /access/groups/{groupid}", + "method": "PUT", + "path": "/access/groups/{groupid}", + "section": "access", + "summary": "update_group", + "description": "Update group data.", + "pathParameters": [ + { + "name": "groupid", + "type": "string", + "required": true, + "format": "pve-groupid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/groups/{groupid}\naccess\nupdate_group\nUpdate group data.\ngroupid string\ncomment string" + }, + { + "id": "GET /access/openid", + "method": "GET", + "path": "/access/openid", + "section": "access", + "summary": "index", + "description": "Directory index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/openid\naccess\nindex\nDirectory index." + }, + { + "id": "POST /access/openid/auth-url", + "method": "POST", + "path": "/access/openid/auth-url", + "section": "access", + "summary": "auth_url", + "description": "Get the OpenId Authorization Url for the specified realm.", + "pathParameters": [], + "requestParameters": [ + { + "name": "realm", + "type": "string", + "required": true, + "description": "Authentication domain ID", + "format": "pve-realm" + }, + { + "name": "redirect-url", + "type": "string", + "required": true, + "description": "Redirection Url. The client should set this to the used server url (location.origin)." + } + ], + "returns": { + "description": "Redirection URL.", + "type": "string" + }, + "permissions": { + "user": "world" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/openid/auth-url\naccess\nauth_url\nGet the OpenId Authorization Url for the specified realm.\nrealm string Authentication domain ID\nredirect-url string Redirection Url. The client should set this to the used server url (location.origin)." + }, + { + "id": "POST /access/openid/login", + "method": "POST", + "path": "/access/openid/login", + "section": "access", + "summary": "login", + "description": "Verify OpenID authorization code and create a ticket.", + "pathParameters": [], + "requestParameters": [ + { + "name": "code", + "type": "string", + "required": true, + "description": "OpenId authorization code." + }, + { + "name": "redirect-url", + "type": "string", + "required": true, + "description": "Redirection Url. The client should set this to the used server url (location.origin)." + }, + { + "name": "state", + "type": "string", + "required": true, + "description": "OpenId state." + } + ], + "returns": { + "properties": { + "CSRFPreventionToken": { + "type": "string" + }, + "cap": { + "type": "object" + }, + "clustername": { + "optional": 1, + "type": "string" + }, + "ticket": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "permissions": { + "user": "world" + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/access/openid/login\naccess\nlogin\nVerify OpenID authorization code and create a ticket.\ncode string OpenId authorization code.\nredirect-url string Redirection Url. The client should set this to the used server url (location.origin).\nstate string OpenId state." + }, + { + "id": "PUT /access/password", + "method": "PUT", + "path": "/access/password", + "section": "access", + "summary": "change_password", + "description": "Change user password.", + "pathParameters": [], + "requestParameters": [ + { + "name": "password", + "type": "string", + "required": true, + "description": "The new password." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + }, + { + "name": "confirmation-password", + "type": "string", + "required": false, + "description": "The current password of the user performing the change." + } + ], + "returns": { + "type": "null" + }, + "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." + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/password\naccess\nchange_password\nChange user password.\npassword string The new password.\nuserid string Full User ID, in the `name@realm` format.\nconfirmation-password string The current password of the user performing the change." + }, + { + "id": "GET /access/permissions", + "method": "GET", + "path": "/access/permissions", + "section": "access", + "summary": "permissions", + "description": "Retrieve effective permissions of given user/token.", + "pathParameters": [], + "requestParameters": [ + { + "name": "path", + "type": "string", + "required": false, + "description": "Only dump this specific path, not the whole tree." + }, + { + "name": "userid", + "type": "string", + "required": false, + "description": "User ID or full API token ID" + } + ], + "returns": { + "description": "Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").", + "type": "object" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/permissions\naccess\npermissions\nRetrieve effective permissions of given user/token.\npath string Only dump this specific path, not the whole tree.\nuserid string User ID or full API token ID" + }, + { + "id": "GET /access/roles", + "method": "GET", + "path": "/access/roles", + "section": "access", + "summary": "index", + "description": "Role index.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/roles\naccess\nindex\nRole index." + }, + { + "id": "POST /access/roles", + "method": "POST", + "path": "/access/roles", + "section": "access", + "summary": "create_role", + "description": "Create new role.", + "pathParameters": [], + "requestParameters": [ + { + "name": "roleid", + "type": "string", + "required": true, + "format": "pve-roleid" + }, + { + "name": "privs", + "type": "string", + "required": false, + "format": "pve-priv-list" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/roles\naccess\ncreate_role\nCreate new role.\nroleid string\nprivs string" + }, + { + "id": "DELETE /access/roles/{roleid}", + "method": "DELETE", + "path": "/access/roles/{roleid}", + "section": "access", + "summary": "delete_role", + "description": "Delete role.", + "pathParameters": [ + { + "name": "roleid", + "type": "string", + "required": true, + "format": "pve-roleid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/access/roles/{roleid}\naccess\ndelete_role\nDelete role.\nroleid string" + }, + { + "id": "GET /access/roles/{roleid}", + "method": "GET", + "path": "/access/roles/{roleid}", + "section": "access", + "summary": "read_role", + "description": "Get role configuration.", + "pathParameters": [ + { + "name": "roleid", + "type": "string", + "required": true, + "format": "pve-roleid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/roles/{roleid}\naccess\nread_role\nGet role configuration.\nroleid string" + }, + { + "id": "PUT /access/roles/{roleid}", + "method": "PUT", + "path": "/access/roles/{roleid}", + "section": "access", + "summary": "update_role", + "description": "Update an existing role.", + "pathParameters": [ + { + "name": "roleid", + "type": "string", + "required": true, + "format": "pve-roleid" + } + ], + "requestParameters": [ + { + "name": "append", + "type": "boolean", + "required": false + }, + { + "name": "privs", + "type": "string", + "required": false, + "format": "pve-priv-list" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/roles/{roleid}\naccess\nupdate_role\nUpdate an existing role.\nroleid string\nappend boolean\nprivs string" + }, + { + "id": "GET /access/tfa", + "method": "GET", + "path": "/access/tfa", + "section": "access", + "summary": "list_tfa", + "description": "List TFA configurations of users.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Returns all or just the logged-in user, depending on privileges.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/tfa\naccess\nlist_tfa\nList TFA configurations of users." + }, + { + "id": "GET /access/tfa/{userid}", + "method": "GET", + "path": "/access/tfa/{userid}", + "section": "access", + "summary": "list_user_tfa", + "description": "List TFA configurations of users.", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/tfa/{userid}\naccess\nlist_user_tfa\nList TFA configurations of users.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "POST /access/tfa/{userid}", + "method": "POST", + "path": "/access/tfa/{userid}", + "section": "access", + "summary": "add_tfa_entry", + "description": "Add a TFA entry for a user.", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": true, + "description": "TFA Entry Type.", + "enum": [ + "totp", + "u2f", + "webauthn", + "recovery", + "yubico" + ] + }, + { + "name": "challenge", + "type": "string", + "required": false, + "description": "When responding to a u2f challenge: the original challenge string" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "A description to distinguish multiple entries from one another" + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "The current password of the user performing the change." + }, + { + "name": "totp", + "type": "string", + "required": false, + "description": "A totp URI." + }, + { + "name": "value", + "type": "string", + "required": false, + "description": "The current value for the provided totp URI, or a Webauthn/U2F challenge response" + } + ], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/tfa/{userid}\naccess\nadd_tfa_entry\nAdd a TFA entry for a user.\nuserid string Full User ID, in the `name@realm` format.\ntype string TFA Entry Type. totp u2f webauthn recovery yubico\nchallenge string When responding to a u2f challenge: the original challenge string\ndescription string A description to distinguish multiple entries from one another\npassword string The current password of the user performing the change.\ntotp string A totp URI.\nvalue string The current value for the provided totp URI, or a Webauthn/U2F challenge response" + }, + { + "id": "DELETE /access/tfa/{userid}/{id}", + "method": "DELETE", + "path": "/access/tfa/{userid}/{id}", + "section": "access", + "summary": "delete_tfa", + "description": "Delete a TFA entry by ID.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "A TFA entry id." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [ + { + "name": "password", + "type": "string", + "required": false, + "description": "The current password of the user performing the change." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/access/tfa/{userid}/{id}\naccess\ndelete_tfa\nDelete a TFA entry by ID.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format.\npassword string The current password of the user performing the change." + }, + { + "id": "GET /access/tfa/{userid}/{id}", + "method": "GET", + "path": "/access/tfa/{userid}/{id}", + "section": "access", + "summary": "get_tfa_entry", + "description": "Fetch a requested TFA entry if present.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "A TFA entry id." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/tfa/{userid}/{id}\naccess\nget_tfa_entry\nFetch a requested TFA entry if present.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "PUT /access/tfa/{userid}/{id}", + "method": "PUT", + "path": "/access/tfa/{userid}/{id}", + "section": "access", + "summary": "update_tfa_entry", + "description": "Add a TFA entry for a user.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "A TFA entry id." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [ + { + "name": "description", + "type": "string", + "required": false, + "description": "A description to distinguish multiple entries from one another" + }, + { + "name": "enable", + "type": "boolean", + "required": false, + "description": "Whether the entry should be enabled for login." + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "The current password of the user performing the change." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/tfa/{userid}/{id}\naccess\nupdate_tfa_entry\nAdd a TFA entry for a user.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format.\ndescription string A description to distinguish multiple entries from one another\nenable boolean Whether the entry should be enabled for login.\npassword string The current password of the user performing the change." + }, + { + "id": "GET /access/ticket", + "method": "GET", + "path": "/access/ticket", + "section": "access", + "summary": "get_ticket", + "description": "Dummy. Useful for formatters which want to provide a login page.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "user": "world" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/ticket\naccess\nget_ticket\nDummy. Useful for formatters which want to provide a login page." + }, + { + "id": "POST /access/ticket", + "method": "POST", + "path": "/access/ticket", + "section": "access", + "summary": "create_ticket", + "description": "Create or verify authentication ticket.", + "pathParameters": [], + "requestParameters": [ + { + "name": "password", + "type": "string", + "required": true, + "description": "The secret password. This can also be a valid ticket." + }, + { + "name": "username", + "type": "string", + "required": true, + "description": "User name" + }, + { + "name": "new-format", + "type": "boolean", + "required": false, + "description": "This parameter is now ignored and assumed to be 1.", + "default": 1 + }, + { + "name": "otp", + "type": "string", + "required": false, + "description": "One-time password for Two-factor authentication." + }, + { + "name": "path", + "type": "string", + "required": false, + "description": "Verify ticket, and check if user have access 'privs' on 'path'" + }, + { + "name": "privs", + "type": "string", + "required": false, + "description": "Verify ticket, and check if user have access 'privs' on 'path'", + "format": "pve-priv-list" + }, + { + "name": "realm", + "type": "string", + "required": false, + "description": "You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.", + "format": "pve-realm" + }, + { + "name": "tfa-challenge", + "type": "string", + "required": false, + "description": "The signed TFA challenge string the user wants to respond to." + } + ], + "returns": { + "properties": { + "CSRFPreventionToken": { + "optional": 1, + "type": "string" + }, + "clustername": { + "optional": 1, + "type": "string" + }, + "ticket": { + "optional": 1, + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "description": "You need to pass valid credientials.", + "user": "world" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/ticket\naccess\ncreate_ticket\nCreate or verify authentication ticket.\npassword string The secret password. This can also be a valid ticket.\nusername string User name\nnew-format boolean This parameter is now ignored and assumed to be 1.\notp string One-time password for Two-factor authentication.\npath string Verify ticket, and check if user have access 'privs' on 'path'\nprivs string Verify ticket, and check if user have access 'privs' on 'path'\nrealm string You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.\ntfa-challenge string The signed TFA challenge string the user wants to respond to." + }, + { + "id": "GET /access/users", + "method": "GET", + "path": "/access/users", + "section": "access", + "summary": "index", + "description": "User index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "enabled", + "type": "boolean", + "required": false, + "description": "Optional filter for enable property." + }, + { + "name": "full", + "type": "boolean", + "required": false, + "description": "Include group and token information.", + "default": 0 + } + ], + "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" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/users\naccess\nindex\nUser index.\nenabled boolean Optional filter for enable property.\nfull boolean Include group and token information." + }, + { + "id": "POST /access/users", + "method": "POST", + "path": "/access/users", + "section": "access", + "summary": "create_user", + "description": "Create new user.", + "pathParameters": [], + "requestParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "email", + "type": "string", + "required": false, + "format": "email-opt" + }, + { + "name": "enable", + "type": "boolean", + "required": false, + "description": "Enable the account (default). You can set this to '0' to disable the account", + "default": 1 + }, + { + "name": "expire", + "type": "integer", + "required": false, + "description": "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum": 0 + }, + { + "name": "firstname", + "type": "string", + "required": false + }, + { + "name": "groups", + "type": "string", + "required": false, + "format": "pve-groupid-list" + }, + { + "name": "keys", + "type": "string", + "required": false, + "description": "Keys for two factor auth (yubico)." + }, + { + "name": "lastname", + "type": "string", + "required": false + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "Initial password." + } + ], + "returns": { + "type": "null" + }, + "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." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/users\naccess\ncreate_user\nCreate new user.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\nemail string\nenable boolean Enable the account (default). You can set this to '0' to disable the account\nexpire integer Account expiration date (seconds since epoch). '0' means no expiration date.\nfirstname string\ngroups string\nkeys string Keys for two factor auth (yubico).\nlastname string\npassword string Initial password." + }, + { + "id": "DELETE /access/users/{userid}", + "method": "DELETE", + "path": "/access/users/{userid}", + "section": "access", + "summary": "delete_user", + "description": "Delete user.", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/access/users/{userid}\naccess\ndelete_user\nDelete user.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "GET /access/users/{userid}", + "method": "GET", + "path": "/access/users/{userid}", + "section": "access", + "summary": "read_user", + "description": "Get user configuration.", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/users/{userid}\naccess\nread_user\nGet user configuration.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "PUT /access/users/{userid}", + "method": "PUT", + "path": "/access/users/{userid}", + "section": "access", + "summary": "update_user", + "description": "Update user configuration.", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [ + { + "name": "append", + "type": "boolean", + "required": false + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "email", + "type": "string", + "required": false, + "format": "email-opt" + }, + { + "name": "enable", + "type": "boolean", + "required": false, + "description": "Enable the account (default). You can set this to '0' to disable the account", + "default": 1 + }, + { + "name": "expire", + "type": "integer", + "required": false, + "description": "Account expiration date (seconds since epoch). '0' means no expiration date.", + "minimum": 0 + }, + { + "name": "firstname", + "type": "string", + "required": false + }, + { + "name": "groups", + "type": "string", + "required": false, + "format": "pve-groupid-list" + }, + { + "name": "keys", + "type": "string", + "required": false, + "description": "Keys for two factor auth (yubico)." + }, + { + "name": "lastname", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "update" + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/users/{userid}\naccess\nupdate_user\nUpdate user configuration.\nuserid string Full User ID, in the `name@realm` format.\nappend boolean\ncomment string\nemail string\nenable boolean Enable the account (default). You can set this to '0' to disable the account\nexpire integer Account expiration date (seconds since epoch). '0' means no expiration date.\nfirstname string\ngroups string\nkeys string Keys for two factor auth (yubico).\nlastname string" + }, + { + "id": "GET /access/users/{userid}/tfa", + "method": "GET", + "path": "/access/users/{userid}/tfa", + "section": "access", + "summary": "read_user_tfa_type", + "description": "Get user TFA types (Personal and Realm).", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [ + { + "name": "multiple", + "type": "boolean", + "required": false, + "description": "Request all entries as an array.", + "default": 0 + } + ], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/users/{userid}/tfa\naccess\nread_user_tfa_type\nGet user TFA types (Personal and Realm).\nuserid string Full User ID, in the `name@realm` format.\nmultiple boolean Request all entries as an array." + }, + { + "id": "GET /access/users/{userid}/token", + "method": "GET", + "path": "/access/users/{userid}/token", + "section": "access", + "summary": "token_index", + "description": "Get user API tokens.", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/users/{userid}/token\naccess\ntoken_index\nGet user API tokens.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "DELETE /access/users/{userid}/token/{tokenid}", + "method": "DELETE", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "remove_token", + "description": "Remove API token for a specific user.", + "pathParameters": [ + { + "name": "tokenid", + "type": "string", + "required": true, + "description": "User-specific token identifier." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/access/users/{userid}/token/{tokenid}\naccess\nremove_token\nRemove API token for a specific user.\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "GET /access/users/{userid}/token/{tokenid}", + "method": "GET", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "read_token", + "description": "Get specific API token information.", + "pathParameters": [ + { + "name": "tokenid", + "type": "string", + "required": true, + "description": "User-specific token identifier." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/access/users/{userid}/token/{tokenid}\naccess\nread_token\nGet specific API token information.\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "POST /access/users/{userid}/token/{tokenid}", + "method": "POST", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "generate_token", + "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!", + "pathParameters": [ + { + "name": "tokenid", + "type": "string", + "required": true, + "description": "User-specific token identifier." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "expire", + "type": "integer", + "required": false, + "description": "API token expiration date (seconds since epoch). '0' means no expiration date.", + "default": "same as user", + "minimum": 0 + }, + { + "name": "privsep", + "type": "boolean", + "required": false, + "description": "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "default": 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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/users/{userid}/token/{tokenid}\naccess\ngenerate_token\nGenerate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\nexpire integer API token expiration date (seconds since epoch). '0' means no expiration date.\nprivsep boolean Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user." + }, + { + "id": "PUT /access/users/{userid}/token/{tokenid}", + "method": "PUT", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "update_token_info", + "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!", + "pathParameters": [ + { + "name": "tokenid", + "type": "string", + "required": true, + "description": "User-specific token identifier." + }, + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "expire", + "type": "integer", + "required": false, + "description": "API token expiration date (seconds since epoch). '0' means no expiration date.", + "default": "same as user", + "minimum": 0 + }, + { + "name": "privsep", + "type": "boolean", + "required": false, + "description": "Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.", + "default": 1 + }, + { + "name": "regenerate", + "type": "boolean", + "required": false, + "description": "Regenerate the token's secret value. All users of the previous secret will lose access after this operation.", + "default": 0 + } + ], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/users/{userid}/token/{tokenid}\naccess\nupdate_token_info\nUpdate 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!\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\ndelete string A list of settings you want to delete.\nexpire integer API token expiration date (seconds since epoch). '0' means no expiration date.\nprivsep boolean Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.\nregenerate boolean Regenerate the token's secret value. All users of the previous secret will lose access after this operation." + }, + { + "id": "PUT /access/users/{userid}/unlock-tfa", + "method": "PUT", + "path": "/access/users/{userid}/unlock-tfa", + "section": "access", + "summary": "unlock_tfa", + "description": "Unlock a user's TFA authentication.", + "pathParameters": [ + { + "name": "userid", + "type": "string", + "required": true, + "description": "Full User ID, in the `name@realm` format.", + "format": "pve-userid" + } + ], + "requestParameters": [], + "returns": { + "type": "boolean" + }, + "permissions": { + "check": [ + "userid-group", + [ + "User.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/access/users/{userid}/unlock-tfa\naccess\nunlock_tfa\nUnlock a user's TFA authentication.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "POST /access/vncticket", + "method": "POST", + "path": "/access/vncticket", + "section": "access", + "summary": "verify_vnc_ticket", + "description": "verify VNC authentication ticket.", + "pathParameters": [], + "requestParameters": [ + { + "name": "authid", + "type": "string", + "required": true, + "description": "UserId or token" + }, + { + "name": "path", + "type": "string", + "required": true, + "description": "Verify ticket, and check if user have access 'privs' on 'path'" + }, + { + "name": "privs", + "type": "string", + "required": true, + "description": "Verify ticket, and check if user have access 'privs' on 'path'", + "format": "pve-priv-list" + }, + { + "name": "vncticket", + "type": "string", + "required": true, + "description": "The VNC ticket." + }, + { + "name": "port", + "type": "integer", + "required": false, + "description": "Verify that the ticket is valid for this port." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "You need to pass valid credientials.", + "user": "world" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/access/vncticket\naccess\nverify_vnc_ticket\nverify VNC authentication ticket.\nauthid string UserId or token\npath string Verify ticket, and check if user have access 'privs' on 'path'\nprivs string Verify ticket, and check if user have access 'privs' on 'path'\nvncticket string The VNC ticket.\nport integer Verify that the ticket is valid for this port." + }, + { + "id": "GET /cluster", + "method": "GET", + "path": "/cluster", + "section": "cluster", + "summary": "index", + "description": "Cluster index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster\ncluster\nindex\nCluster index." + }, + { + "id": "GET /cluster/acme", + "method": "GET", + "path": "/cluster/acme", + "section": "cluster", + "summary": "index", + "description": "ACMEAccount index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme\ncluster\nindex\nACMEAccount index." + }, + { + "id": "GET /cluster/acme/account", + "method": "GET", + "path": "/cluster/acme/account", + "section": "cluster", + "summary": "account_index", + "description": "ACMEAccount index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/account\ncluster\naccount_index\nACMEAccount index." + }, + { + "id": "POST /cluster/acme/account", + "method": "POST", + "path": "/cluster/acme/account", + "section": "cluster", + "summary": "register_account", + "description": "Register a new ACME account with CA.", + "pathParameters": [], + "requestParameters": [ + { + "name": "contact", + "type": "string", + "required": true, + "description": "Contact email addresses.", + "format": "email-list" + }, + { + "name": "directory", + "type": "string", + "required": false, + "description": "URL of ACME CA directory endpoint.", + "default": "https://acme-v02.api.letsencrypt.org/directory" + }, + { + "name": "eab-hmac-key", + "type": "string", + "required": false, + "description": "HMAC key for External Account Binding." + }, + { + "name": "eab-kid", + "type": "string", + "required": false, + "description": "Key Identifier for External Account Binding." + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "ACME account config file name.", + "default": "default", + "format": "pve-configid" + }, + { + "name": "tos_url", + "type": "string", + "required": false, + "description": "URL of CA TermsOfService - setting this indicates agreement." + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/acme/account\ncluster\nregister_account\nRegister a new ACME account with CA.\ncontact string Contact email addresses.\ndirectory string URL of ACME CA directory endpoint.\neab-hmac-key string HMAC key for External Account Binding.\neab-kid string Key Identifier for External Account Binding.\nname string ACME account config file name.\ntos_url string URL of CA TermsOfService - setting this indicates agreement." + }, + { + "id": "DELETE /cluster/acme/account/{name}", + "method": "DELETE", + "path": "/cluster/acme/account/{name}", + "section": "cluster", + "summary": "deactivate_account", + "description": "Deactivate existing ACME account at CA.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": false, + "description": "ACME account config file name.", + "default": "default", + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/acme/account/{name}\ncluster\ndeactivate_account\nDeactivate existing ACME account at CA.\nname string ACME account config file name." + }, + { + "id": "GET /cluster/acme/account/{name}", + "method": "GET", + "path": "/cluster/acme/account/{name}", + "section": "cluster", + "summary": "get_account", + "description": "Return existing ACME account information.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": false, + "description": "ACME account config file name.", + "default": "default", + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/account/{name}\ncluster\nget_account\nReturn existing ACME account information.\nname string ACME account config file name." + }, + { + "id": "PUT /cluster/acme/account/{name}", + "method": "PUT", + "path": "/cluster/acme/account/{name}", + "section": "cluster", + "summary": "update_account", + "description": "Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": false, + "description": "ACME account config file name.", + "default": "default", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "contact", + "type": "string", + "required": false, + "description": "Contact email addresses.", + "format": "email-list" + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/acme/account/{name}\ncluster\nupdate_account\nUpdate existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.\nname string ACME account config file name.\ncontact string Contact email addresses." + }, + { + "id": "GET /cluster/acme/challenge-schema", + "method": "GET", + "path": "/cluster/acme/challenge-schema", + "section": "cluster", + "summary": "challengeschema", + "description": "Get schema of ACME challenge types.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/challenge-schema\ncluster\nchallengeschema\nGet schema of ACME challenge types." + }, + { + "id": "GET /cluster/acme/directories", + "method": "GET", + "path": "/cluster/acme/directories", + "section": "cluster", + "summary": "get_directories", + "description": "Get named known ACME directory endpoints.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "additionalProperties": 0, + "properties": { + "name": { + "type": "string" + }, + "url": { + "description": "URL of ACME CA directory endpoint.", + "pattern": "^https?://.*", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/directories\ncluster\nget_directories\nGet named known ACME directory endpoints." + }, + { + "id": "GET /cluster/acme/meta", + "method": "GET", + "path": "/cluster/acme/meta", + "section": "cluster", + "summary": "get_meta", + "description": "Retrieve ACME Directory Meta Information", + "pathParameters": [], + "requestParameters": [ + { + "name": "directory", + "type": "string", + "required": false, + "description": "URL of ACME CA directory endpoint.", + "default": "https://acme-v02.api.letsencrypt.org/directory" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/meta\ncluster\nget_meta\nRetrieve ACME Directory Meta Information\ndirectory string URL of ACME CA directory endpoint." + }, + { + "id": "GET /cluster/acme/plugins", + "method": "GET", + "path": "/cluster/acme/plugins", + "section": "cluster", + "summary": "index", + "description": "ACME plugin index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list ACME plugins of a specific type", + "enum": [ + "dns", + "standalone" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/plugins\ncluster\nindex\nACME plugin index.\ntype string Only list ACME plugins of a specific type dns standalone" + }, + { + "id": "POST /cluster/acme/plugins", + "method": "POST", + "path": "/cluster/acme/plugins", + "section": "cluster", + "summary": "add_plugin", + "description": "Add ACME plugin configuration.", + "pathParameters": [], + "requestParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "ACME Plugin ID name", + "format": "pve-configid" + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "ACME challenge type.", + "enum": [ + "dns", + "standalone" + ] + }, + { + "name": "api", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "data", + "type": "string", + "required": false, + "description": "DNS plugin data. (base64 encoded)" + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable the config." + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "validation-delay", + "type": "integer", + "required": false, + "description": "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "default": 30, + "minimum": 0, + "maximum": 172800 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/acme/plugins\ncluster\nadd_plugin\nAdd ACME plugin configuration.\nid string ACME Plugin ID name\ntype string ACME challenge type. dns standalone\napi string API plugin name 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\ndata string DNS plugin data. (base64 encoded)\ndisable boolean Flag to disable the config.\nnodes string List of cluster node names.\nvalidation-delay integer Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records." + }, + { + "id": "DELETE /cluster/acme/plugins/{id}", + "method": "DELETE", + "path": "/cluster/acme/plugins/{id}", + "section": "cluster", + "summary": "delete_plugin", + "description": "Delete ACME plugin configuration.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "Unique identifier for ACME plugin instance.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/acme/plugins/{id}\ncluster\ndelete_plugin\nDelete ACME plugin configuration.\nid string Unique identifier for ACME plugin instance." + }, + { + "id": "GET /cluster/acme/plugins/{id}", + "method": "GET", + "path": "/cluster/acme/plugins/{id}", + "section": "cluster", + "summary": "get_plugin_config", + "description": "Get ACME plugin configuration.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "Unique identifier for ACME plugin instance.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/plugins/{id}\ncluster\nget_plugin_config\nGet ACME plugin configuration.\nid string Unique identifier for ACME plugin instance." + }, + { + "id": "PUT /cluster/acme/plugins/{id}", + "method": "PUT", + "path": "/cluster/acme/plugins/{id}", + "section": "cluster", + "summary": "update_plugin", + "description": "Update ACME plugin configuration.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "ACME Plugin ID name", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "api", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "data", + "type": "string", + "required": false, + "description": "DNS plugin data. (base64 encoded)" + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable the config." + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "validation-delay", + "type": "integer", + "required": false, + "description": "Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.", + "default": 30, + "minimum": 0, + "maximum": 172800 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/acme/plugins/{id}\ncluster\nupdate_plugin\nUpdate ACME plugin configuration.\nid string ACME Plugin ID name\napi string API plugin name 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\ndata string DNS plugin data. (base64 encoded)\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the config.\nnodes string List of cluster node names.\nvalidation-delay integer Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records." + }, + { + "id": "GET /cluster/acme/tos", + "method": "GET", + "path": "/cluster/acme/tos", + "section": "cluster", + "summary": "get_tos", + "description": "Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.", + "pathParameters": [], + "requestParameters": [ + { + "name": "directory", + "type": "string", + "required": false, + "description": "URL of ACME CA directory endpoint.", + "default": "https://acme-v02.api.letsencrypt.org/directory" + } + ], + "returns": { + "description": "ACME TermsOfService URL.", + "optional": 1, + "type": "string" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/acme/tos\ncluster\nget_tos\nRetrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.\ndirectory string URL of ACME CA directory endpoint." + }, + { + "id": "GET /cluster/backup", + "method": "GET", + "path": "/cluster/backup", + "section": "cluster", + "summary": "index", + "description": "List vzdump backup schedule.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/backup\ncluster\nindex\nList vzdump backup schedule." + }, + { + "id": "POST /cluster/backup", + "method": "POST", + "path": "/cluster/backup", + "section": "cluster", + "summary": "create_job", + "description": "Create new vzdump backup job.", + "pathParameters": [], + "requestParameters": [ + { + "name": "all", + "type": "boolean", + "required": false, + "description": "Backup all known guest systems on this host.", + "default": 0 + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Limit I/O bandwidth (in KiB/s).", + "default": 0, + "minimum": 0 + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description for the Job." + }, + { + "name": "compress", + "type": "string", + "required": false, + "description": "Compress dump file.", + "enum": [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "default": "0" + }, + { + "name": "dow", + "type": "string", + "required": false, + "description": "Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.", + "default": "mon,tue,wed,thu,fri,sat,sun", + "format": "pve-day-of-week-list" + }, + { + "name": "dumpdir", + "type": "string", + "required": false, + "description": "Store resulting files to specified directory." + }, + { + "name": "enabled", + "type": "boolean", + "required": false, + "description": "Enable or disable the job.", + "default": "1" + }, + { + "name": "exclude", + "type": "string", + "required": false, + "description": "Exclude specified guest systems (assumes --all)", + "format": "pve-vmid-list" + }, + { + "name": "exclude-path", + "type": "array", + "required": false, + "description": "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory." + }, + { + "name": "fleecing", + "type": "string", + "required": false, + "description": "Options for backup fleecing (VM only).", + "format": "backup-fleecing" + }, + { + "name": "id", + "type": "string", + "required": false, + "description": "Job ID (will be autogenerated).", + "format": "pve-configid" + }, + { + "name": "ionice", + "type": "integer", + "required": false, + "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.", + "default": 7, + "minimum": 0, + "maximum": 8 + }, + { + "name": "lockwait", + "type": "integer", + "required": false, + "description": "Maximal time to wait for the global lock (minutes).", + "default": 180, + "minimum": 0 + }, + { + "name": "mailnotification", + "type": "string", + "required": false, + "description": "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum": [ + "always", + "failure" + ], + "default": "always" + }, + { + "name": "mailto", + "type": "string", + "required": false, + "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" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Backup mode.", + "enum": [ + "snapshot", + "suspend", + "stop" + ], + "default": "snapshot" + }, + { + "name": "node", + "type": "string", + "required": false, + "description": "Only run if executed on this node.", + "format": "pve-node" + }, + { + "name": "notes-template", + "type": "string", + "required": false, + "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." + }, + { + "name": "notification-mode", + "type": "string", + "required": false, + "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" + ], + "default": "auto" + }, + { + "name": "pbs-change-detection-mode", + "type": "string", + "required": false, + "description": "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum": [ + "legacy", + "data", + "metadata" + ] + }, + { + "name": "performance", + "type": "string", + "required": false, + "description": "Other performance-related settings.", + "format": "backup-performance" + }, + { + "name": "pigz", + "type": "integer", + "required": false, + "description": "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "default": 0 + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Backup all known guest systems included in the specified pool." + }, + { + "name": "protected", + "type": "boolean", + "required": false, + "description": "If true, mark backup(s) as protected." + }, + { + "name": "prune-backups", + "type": "string", + "required": false, + "description": "Use these retention options instead of those from the storage configuration.", + "default": "keep-all=1", + "format": "prune-backups" + }, + { + "name": "quiet", + "type": "boolean", + "required": false, + "description": "Be quiet.", + "default": 0 + }, + { + "name": "remove", + "type": "boolean", + "required": false, + "description": "Prune older backups according to 'prune-backups'.", + "default": 1 + }, + { + "name": "repeat-missed", + "type": "boolean", + "required": false, + "description": "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "default": 0 + }, + { + "name": "schedule", + "type": "string", + "required": false, + "description": "Backup schedule. The format is a subset of `systemd` calendar events.", + "format": "pve-calendar-event" + }, + { + "name": "script", + "type": "string", + "required": false, + "description": "Use specified hook script." + }, + { + "name": "starttime", + "type": "string", + "required": false, + "description": "Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used." + }, + { + "name": "stdexcludes", + "type": "boolean", + "required": false, + "description": "Exclude temporary files and logs.", + "default": 1 + }, + { + "name": "stop", + "type": "boolean", + "required": false, + "description": "Stop running backup jobs on this host.", + "default": 0 + }, + { + "name": "stopwait", + "type": "integer", + "required": false, + "description": "Maximal time to wait until a guest system is stopped (minutes).", + "default": 10, + "minimum": 0 + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Store resulting file to this storage.", + "format": "pve-storage-id" + }, + { + "name": "tmpdir", + "type": "string", + "required": false, + "description": "Store temporary files to specified directory." + }, + { + "name": "vmid", + "type": "string", + "required": false, + "description": "The ID of the guest system you want to backup.", + "format": "pve-vmid-list" + }, + { + "name": "zstd", + "type": "integer", + "required": false, + "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.", + "default": 1 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/backup\ncluster\ncreate_job\nCreate new vzdump backup job.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncomment string Description for the Job.\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndow string Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.\ndumpdir string Store resulting files to specified directory.\nenabled boolean Enable or disable the job.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nid string Job ID (will be autogenerated).\nionice integer 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnode string Only run if executed on this node.\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nrepeat-missed boolean If true, the job will be run as soon as possible if it was missed while the scheduler was not running.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\nscript string Use specified hook script.\nstarttime string Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.\nstdexcludes boolean Exclude temporary files and logs.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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." + }, + { + "id": "GET /cluster/backup-info", + "method": "GET", + "path": "/cluster/backup-info", + "section": "cluster", + "summary": "index", + "description": "Index for backup info related endpoints", + "pathParameters": [], + "requestParameters": [], + "returns": { + "description": "Directory index.", + "items": { + "properties": { + "subdir": { + "description": "API sub-directory endpoint", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/backup-info\ncluster\nindex\nIndex for backup info related endpoints" + }, + { + "id": "GET /cluster/backup-info/not-backed-up", + "method": "GET", + "path": "/cluster/backup-info/not-backed-up", + "section": "cluster", + "summary": "get_guests_not_in_backup", + "description": "Shows all guests which are not covered by any backup job.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/backup-info/not-backed-up\ncluster\nget_guests_not_in_backup\nShows all guests which are not covered by any backup job." + }, + { + "id": "DELETE /cluster/backup/{id}", + "method": "DELETE", + "path": "/cluster/backup/{id}", + "section": "cluster", + "summary": "delete_job", + "description": "Delete vzdump backup job definition.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The job ID." + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/backup/{id}\ncluster\ndelete_job\nDelete vzdump backup job definition.\nid string The job ID." + }, + { + "id": "GET /cluster/backup/{id}", + "method": "GET", + "path": "/cluster/backup/{id}", + "section": "cluster", + "summary": "read_job", + "description": "Read vzdump backup job definition.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The job ID." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/backup/{id}\ncluster\nread_job\nRead vzdump backup job definition.\nid string The job ID." + }, + { + "id": "PUT /cluster/backup/{id}", + "method": "PUT", + "path": "/cluster/backup/{id}", + "section": "cluster", + "summary": "update_job", + "description": "Update vzdump backup job definition.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The job ID." + } + ], + "requestParameters": [ + { + "name": "all", + "type": "boolean", + "required": false, + "description": "Backup all known guest systems on this host.", + "default": 0 + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Limit I/O bandwidth (in KiB/s).", + "default": 0, + "minimum": 0 + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description for the Job." + }, + { + "name": "compress", + "type": "string", + "required": false, + "description": "Compress dump file.", + "enum": [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "default": "0" + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dow", + "type": "string", + "required": false, + "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" + }, + { + "name": "dumpdir", + "type": "string", + "required": false, + "description": "Store resulting files to specified directory." + }, + { + "name": "enabled", + "type": "boolean", + "required": false, + "description": "Enable or disable the job.", + "default": "1" + }, + { + "name": "exclude", + "type": "string", + "required": false, + "description": "Exclude specified guest systems (assumes --all)", + "format": "pve-vmid-list" + }, + { + "name": "exclude-path", + "type": "array", + "required": false, + "description": "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory." + }, + { + "name": "fleecing", + "type": "string", + "required": false, + "description": "Options for backup fleecing (VM only).", + "format": "backup-fleecing" + }, + { + "name": "ionice", + "type": "integer", + "required": false, + "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.", + "default": 7, + "minimum": 0, + "maximum": 8 + }, + { + "name": "lockwait", + "type": "integer", + "required": false, + "description": "Maximal time to wait for the global lock (minutes).", + "default": 180, + "minimum": 0 + }, + { + "name": "mailnotification", + "type": "string", + "required": false, + "description": "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum": [ + "always", + "failure" + ], + "default": "always" + }, + { + "name": "mailto", + "type": "string", + "required": false, + "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" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Backup mode.", + "enum": [ + "snapshot", + "suspend", + "stop" + ], + "default": "snapshot" + }, + { + "name": "node", + "type": "string", + "required": false, + "description": "Only run if executed on this node.", + "format": "pve-node" + }, + { + "name": "notes-template", + "type": "string", + "required": false, + "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." + }, + { + "name": "notification-mode", + "type": "string", + "required": false, + "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" + ], + "default": "auto" + }, + { + "name": "pbs-change-detection-mode", + "type": "string", + "required": false, + "description": "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum": [ + "legacy", + "data", + "metadata" + ] + }, + { + "name": "performance", + "type": "string", + "required": false, + "description": "Other performance-related settings.", + "format": "backup-performance" + }, + { + "name": "pigz", + "type": "integer", + "required": false, + "description": "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "default": 0 + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Backup all known guest systems included in the specified pool." + }, + { + "name": "protected", + "type": "boolean", + "required": false, + "description": "If true, mark backup(s) as protected." + }, + { + "name": "prune-backups", + "type": "string", + "required": false, + "description": "Use these retention options instead of those from the storage configuration.", + "default": "keep-all=1", + "format": "prune-backups" + }, + { + "name": "quiet", + "type": "boolean", + "required": false, + "description": "Be quiet.", + "default": 0 + }, + { + "name": "remove", + "type": "boolean", + "required": false, + "description": "Prune older backups according to 'prune-backups'.", + "default": 1 + }, + { + "name": "repeat-missed", + "type": "boolean", + "required": false, + "description": "If true, the job will be run as soon as possible if it was missed while the scheduler was not running.", + "default": 0 + }, + { + "name": "schedule", + "type": "string", + "required": false, + "description": "Backup schedule. The format is a subset of `systemd` calendar events.", + "format": "pve-calendar-event" + }, + { + "name": "script", + "type": "string", + "required": false, + "description": "Use specified hook script." + }, + { + "name": "starttime", + "type": "string", + "required": false, + "description": "Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used." + }, + { + "name": "stdexcludes", + "type": "boolean", + "required": false, + "description": "Exclude temporary files and logs.", + "default": 1 + }, + { + "name": "stop", + "type": "boolean", + "required": false, + "description": "Stop running backup jobs on this host.", + "default": 0 + }, + { + "name": "stopwait", + "type": "integer", + "required": false, + "description": "Maximal time to wait until a guest system is stopped (minutes).", + "default": 10, + "minimum": 0 + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Store resulting file to this storage.", + "format": "pve-storage-id" + }, + { + "name": "tmpdir", + "type": "string", + "required": false, + "description": "Store temporary files to specified directory." + }, + { + "name": "vmid", + "type": "string", + "required": false, + "description": "The ID of the guest system you want to backup.", + "format": "pve-vmid-list" + }, + { + "name": "zstd", + "type": "integer", + "required": false, + "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.", + "default": 1 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/backup/{id}\ncluster\nupdate_job\nUpdate vzdump backup job definition.\nid string The job ID.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncomment string Description for the Job.\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndelete string A list of settings you want to delete.\ndow string Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.\ndumpdir string Store resulting files to specified directory.\nenabled boolean Enable or disable the job.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nionice integer 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnode string Only run if executed on this node.\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nrepeat-missed boolean If true, the job will be run as soon as possible if it was missed while the scheduler was not running.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\nscript string Use specified hook script.\nstarttime string Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.\nstdexcludes boolean Exclude temporary files and logs.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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." + }, + { + "id": "GET /cluster/backup/{id}/included_volumes", + "method": "GET", + "path": "/cluster/backup/{id}/included_volumes", + "section": "cluster", + "summary": "get_volume_backup_included", + "description": "Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The job ID." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/backup/{id}/included_volumes\ncluster\nget_volume_backup_included\nReturns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.\nid string The job ID." + }, + { + "id": "GET /cluster/bulk-action", + "method": "GET", + "path": "/cluster/bulk-action", + "section": "cluster", + "summary": "index", + "description": "List resource types.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/bulk-action\ncluster\nindex\nList resource types." + }, + { + "id": "GET /cluster/bulk-action/guest", + "method": "GET", + "path": "/cluster/bulk-action/guest", + "section": "cluster", + "summary": "index", + "description": "Bulk action index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/bulk-action/guest\ncluster\nindex\nBulk action index." + }, + { + "id": "POST /cluster/bulk-action/guest/migrate", + "method": "POST", + "path": "/cluster/bulk-action/guest/migrate", + "section": "cluster", + "summary": "migrate", + "description": "Bulk migrate all guests on the cluster.", + "pathParameters": [], + "requestParameters": [ + { + "name": "target", + "type": "string", + "required": true, + "description": "Target node.", + "format": "pve-node" + }, + { + "name": "max-workers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently.", + "default": 1, + "minimum": 1, + "maximum": 64 + }, + { + "name": "maxworkers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "default": 1, + "minimum": 1, + "maximum": 64 + }, + { + "name": "online", + "type": "boolean", + "required": false, + "description": "Enable live migration for VMs and restart migration for CTs." + }, + { + "name": "vms", + "type": "array", + "required": false, + "description": "Only consider guests from this list of VMIDs." + }, + { + "name": "with-local-disks", + "type": "boolean", + "required": false, + "description": "Enable live storage migration for local disk" + } + ], + "returns": { + "description": "UPID of the worker", + "type": "string" + }, + "permissions": { + "description": "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/bulk-action/guest/migrate\ncluster\nmigrate\nBulk migrate all guests on the cluster.\ntarget string Target node.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\nonline boolean Enable live migration for VMs and restart migration for CTs.\nvms array Only consider guests from this list of VMIDs.\nwith-local-disks boolean Enable live storage migration for local disk" + }, + { + "id": "POST /cluster/bulk-action/guest/shutdown", + "method": "POST", + "path": "/cluster/bulk-action/guest/shutdown", + "section": "cluster", + "summary": "shutdown", + "description": "Bulk shutdown all guests on the cluster.", + "pathParameters": [], + "requestParameters": [ + { + "name": "force-stop", + "type": "boolean", + "required": false, + "description": "Makes sure the Guest stops after the timeout.", + "default": 1 + }, + { + "name": "max-workers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently.", + "default": 4, + "minimum": 1, + "maximum": 64 + }, + { + "name": "maxworkers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "default": 4, + "minimum": 1, + "maximum": 64 + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Default shutdown timeout in seconds if none is configured for the guest.", + "default": 180 + }, + { + "name": "vms", + "type": "array", + "required": false, + "description": "Only consider guests from this list of VMIDs." + } + ], + "returns": { + "description": "UPID of the worker", + "type": "string" + }, + "permissions": { + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/bulk-action/guest/shutdown\ncluster\nshutdown\nBulk shutdown all guests on the cluster.\nforce-stop boolean Makes sure the Guest stops after the timeout.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\ntimeout integer Default shutdown timeout in seconds if none is configured for the guest.\nvms array Only consider guests from this list of VMIDs." + }, + { + "id": "POST /cluster/bulk-action/guest/start", + "method": "POST", + "path": "/cluster/bulk-action/guest/start", + "section": "cluster", + "summary": "start", + "description": "Bulk start or resume all guests on the cluster.", + "pathParameters": [], + "requestParameters": [ + { + "name": "max-workers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently.", + "default": 4, + "minimum": 1, + "maximum": 64 + }, + { + "name": "maxworkers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "default": 4, + "minimum": 1, + "maximum": 64 + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration)." + }, + { + "name": "vms", + "type": "array", + "required": false, + "description": "Only consider guests from this list of VMIDs." + } + ], + "returns": { + "description": "UPID of the worker", + "type": "string" + }, + "permissions": { + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/bulk-action/guest/start\ncluster\nstart\nBulk start or resume all guests on the cluster.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\ntimeout integer Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration).\nvms array Only consider guests from this list of VMIDs." + }, + { + "id": "POST /cluster/bulk-action/guest/suspend", + "method": "POST", + "path": "/cluster/bulk-action/guest/suspend", + "section": "cluster", + "summary": "suspend", + "description": "Bulk suspend all guests on the cluster.", + "pathParameters": [], + "requestParameters": [ + { + "name": "max-workers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently.", + "default": 4, + "minimum": 1, + "maximum": 64 + }, + { + "name": "maxworkers", + "type": "integer", + "required": false, + "description": "Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.", + "default": 4, + "minimum": 1, + "maximum": 64 + }, + { + "name": "statestorage", + "type": "string", + "required": false, + "description": "The storage for the VM state.", + "format": "pve-storage-id" + }, + { + "name": "to-disk", + "type": "boolean", + "required": false, + "description": "If set, suspends the guests to disk. Will be resumed on next start.", + "default": 0 + }, + { + "name": "vms", + "type": "array", + "required": false, + "description": "Only consider guests from this list of VMIDs." + } + ], + "returns": { + "description": "UPID of the worker", + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/bulk-action/guest/suspend\ncluster\nsuspend\nBulk suspend all guests on the cluster.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\nstatestorage string The storage for the VM state.\nto-disk boolean If set, suspends the guests to disk. Will be resumed on next start.\nvms array Only consider guests from this list of VMIDs." + }, + { + "id": "GET /cluster/ceph", + "method": "GET", + "path": "/cluster/ceph", + "section": "cluster", + "summary": "cephindex", + "description": "Cluster ceph index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ceph\ncluster\ncephindex\nCluster ceph index." + }, + { + "id": "GET /cluster/ceph/flags", + "method": "GET", + "path": "/cluster/ceph/flags", + "section": "cluster", + "summary": "get_all_flags", + "description": "get the status of all ceph flags", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ceph/flags\ncluster\nget_all_flags\nget the status of all ceph flags" + }, + { + "id": "PUT /cluster/ceph/flags", + "method": "PUT", + "path": "/cluster/ceph/flags", + "section": "cluster", + "summary": "set_flags", + "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.", + "pathParameters": [], + "requestParameters": [ + { + "name": "nobackfill", + "type": "boolean", + "required": false, + "description": "Backfilling of PGs is suspended." + }, + { + "name": "nodeep-scrub", + "type": "boolean", + "required": false, + "description": "Deep Scrubbing is disabled." + }, + { + "name": "nodown", + "type": "boolean", + "required": false, + "description": "OSD failure reports are being ignored, such that the monitors will not mark OSDs down." + }, + { + "name": "noin", + "type": "boolean", + "required": false, + "description": "OSDs that were previously marked out will not be marked back in when they start." + }, + { + "name": "noout", + "type": "boolean", + "required": false, + "description": "OSDs will not automatically be marked out after the configured interval." + }, + { + "name": "norebalance", + "type": "boolean", + "required": false, + "description": "Rebalancing of PGs is suspended." + }, + { + "name": "norecover", + "type": "boolean", + "required": false, + "description": "Recovery of PGs is suspended." + }, + { + "name": "noscrub", + "type": "boolean", + "required": false, + "description": "Scrubbing is disabled." + }, + { + "name": "notieragent", + "type": "boolean", + "required": false, + "description": "Cache tiering activity is suspended." + }, + { + "name": "noup", + "type": "boolean", + "required": false, + "description": "OSDs are not allowed to start." + }, + { + "name": "pause", + "type": "boolean", + "required": false, + "description": "Pauses read and writes." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/ceph/flags\ncluster\nset_flags\nSet/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.\nnobackfill boolean Backfilling of PGs is suspended.\nnodeep-scrub boolean Deep Scrubbing is disabled.\nnodown boolean OSD failure reports are being ignored, such that the monitors will not mark OSDs down.\nnoin boolean OSDs that were previously marked out will not be marked back in when they start.\nnoout boolean OSDs will not automatically be marked out after the configured interval.\nnorebalance boolean Rebalancing of PGs is suspended.\nnorecover boolean Recovery of PGs is suspended.\nnoscrub boolean Scrubbing is disabled.\nnotieragent boolean Cache tiering activity is suspended.\nnoup boolean OSDs are not allowed to start.\npause boolean Pauses read and writes." + }, + { + "id": "GET /cluster/ceph/flags/{flag}", + "method": "GET", + "path": "/cluster/ceph/flags/{flag}", + "section": "cluster", + "summary": "get_flag", + "description": "Get the status of a specific ceph flag.", + "pathParameters": [ + { + "name": "flag", + "type": "string", + "required": true, + "description": "The name of the flag name to get.", + "enum": [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ] + } + ], + "requestParameters": [], + "returns": { + "type": "boolean" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ceph/flags/{flag}\ncluster\nget_flag\nGet the status of a specific ceph flag.\nflag string The name of the flag name to get. nobackfill nodeep-scrub nodown noin noout norebalance norecover noscrub notieragent noup pause" + }, + { + "id": "PUT /cluster/ceph/flags/{flag}", + "method": "PUT", + "path": "/cluster/ceph/flags/{flag}", + "section": "cluster", + "summary": "update_flag", + "description": "Set or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task).", + "pathParameters": [ + { + "name": "flag", + "type": "string", + "required": true, + "description": "The ceph flag to update", + "enum": [ + "nobackfill", + "nodeep-scrub", + "nodown", + "noin", + "noout", + "norebalance", + "norecover", + "noscrub", + "notieragent", + "noup", + "pause" + ] + } + ], + "requestParameters": [ + { + "name": "value", + "type": "boolean", + "required": true, + "description": "The new value of the flag" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/ceph/flags/{flag}\ncluster\nupdate_flag\nSet or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task).\nflag string The ceph flag to update nobackfill nodeep-scrub nodown noin noout norebalance norecover noscrub notieragent noup pause\nvalue boolean The new value of the flag" + }, + { + "id": "GET /cluster/ceph/metadata", + "method": "GET", + "path": "/cluster/ceph/metadata", + "section": "cluster", + "summary": "metadata", + "description": "Get ceph metadata.", + "pathParameters": [], + "requestParameters": [ + { + "name": "scope", + "type": "string", + "required": false, + "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" + ], + "default": "all" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ceph/metadata\ncluster\nmetadata\nGet ceph metadata.\nscope string 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. all versions" + }, + { + "id": "GET /cluster/ceph/status", + "method": "GET", + "path": "/cluster/ceph/status", + "section": "cluster", + "summary": "status", + "description": "Get ceph status.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ceph/status\ncluster\nstatus\nGet ceph status." + }, + { + "id": "GET /cluster/config", + "method": "GET", + "path": "/cluster/config", + "section": "cluster", + "summary": "index", + "description": "Directory index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/config\ncluster\nindex\nDirectory index." + }, + { + "id": "POST /cluster/config", + "method": "POST", + "path": "/cluster/config", + "section": "cluster", + "summary": "create", + "description": "Generate new cluster configuration. If no links given, default to local IP address as link0.", + "pathParameters": [], + "requestParameters": [ + { + "name": "clustername", + "type": "string", + "required": true, + "description": "The name of the cluster.", + "format": "pve-node" + }, + { + "name": "link[n]", + "type": "string", + "required": false, + "description": "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)" + }, + { + "name": "nodeid", + "type": "integer", + "required": false, + "description": "Node id for this node.", + "minimum": 1 + }, + { + "name": "token-coefficient", + "type": "integer", + "required": false, + "description": "Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details.", + "default": 125, + "minimum": 0 + }, + { + "name": "votes", + "type": "integer", + "required": false, + "description": "Number of votes for this node.", + "minimum": 1 + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/config\ncluster\ncreate\nGenerate new cluster configuration. If no links given, default to local IP address as link0.\nclustername string The name of the cluster.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnodeid integer Node id for this node.\ntoken-coefficient integer Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details.\nvotes integer Number of votes for this node." + }, + { + "id": "GET /cluster/config/apiversion", + "method": "GET", + "path": "/cluster/config/apiversion", + "section": "cluster", + "summary": "join_api_version", + "description": "Return the version of the cluster join API available on this node.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "description": "Cluster Join API version, currently 1", + "minimum": 0, + "type": "integer" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/config/apiversion\ncluster\njoin_api_version\nReturn the version of the cluster join API available on this node." + }, + { + "id": "GET /cluster/config/join", + "method": "GET", + "path": "/cluster/config/join", + "section": "cluster", + "summary": "join_info", + "description": "Get information needed to join this cluster over the connected node.", + "pathParameters": [], + "requestParameters": [ + { + "name": "node", + "type": "string", + "required": false, + "description": "The node for which the joinee gets the nodeinfo.", + "default": "current connected node", + "format": "pve-node" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/config/join\ncluster\njoin_info\nGet information needed to join this cluster over the connected node.\nnode string The node for which the joinee gets the nodeinfo." + }, + { + "id": "POST /cluster/config/join", + "method": "POST", + "path": "/cluster/config/join", + "section": "cluster", + "summary": "join", + "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).", + "pathParameters": [], + "requestParameters": [ + { + "name": "fingerprint", + "type": "string", + "required": true, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "hostname", + "type": "string", + "required": true, + "description": "Hostname (or IP) of an existing cluster member." + }, + { + "name": "password", + "type": "string", + "required": true, + "description": "Superuser (root) password of peer node." + }, + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Do not throw error if node already exists." + }, + { + "name": "link[n]", + "type": "string", + "required": false, + "description": "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)" + }, + { + "name": "nodeid", + "type": "integer", + "required": false, + "description": "Node id for this node.", + "minimum": 1 + }, + { + "name": "votes", + "type": "integer", + "required": false, + "description": "Number of votes for this node", + "minimum": 0 + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/config/join\ncluster\njoin\nJoins 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).\nfingerprint string Certificate SHA 256 fingerprint.\nhostname string Hostname (or IP) of an existing cluster member.\npassword string Superuser (root) password of peer node.\nforce boolean Do not throw error if node already exists.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnodeid integer Node id for this node.\nvotes integer Number of votes for this node" + }, + { + "id": "GET /cluster/config/nodes", + "method": "GET", + "path": "/cluster/config/nodes", + "section": "cluster", + "summary": "nodes", + "description": "Corosync node list.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "node": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{node}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/config/nodes\ncluster\nnodes\nCorosync node list." + }, + { + "id": "DELETE /cluster/config/nodes/{node}", + "method": "DELETE", + "path": "/cluster/config/nodes/{node}", + "section": "cluster", + "summary": "delnode", + "description": "Removes a node from the cluster configuration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/config/nodes/{node}\ncluster\ndelnode\nRemoves a node from the cluster configuration.\nnode string The cluster node name." + }, + { + "id": "POST /cluster/config/nodes/{node}", + "method": "POST", + "path": "/cluster/config/nodes/{node}", + "section": "cluster", + "summary": "addnode", + "description": "Adds a node to the cluster configuration. This call is for internal use.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "apiversion", + "type": "integer", + "required": false, + "description": "The JOIN_API_VERSION of the new node." + }, + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Do not throw error if node already exists." + }, + { + "name": "link[n]", + "type": "string", + "required": false, + "description": "Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)" + }, + { + "name": "new_node_ip", + "type": "string", + "required": false, + "description": "IP Address of node to add. Used as fallback if no links are given.", + "format": "ip" + }, + { + "name": "nodeid", + "type": "integer", + "required": false, + "description": "Node id for this node.", + "minimum": 1 + }, + { + "name": "votes", + "type": "integer", + "required": false, + "description": "Number of votes for this node", + "minimum": 0 + } + ], + "returns": { + "properties": { + "corosync_authkey": { + "type": "string" + }, + "corosync_conf": { + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/config/nodes/{node}\ncluster\naddnode\nAdds a node to the cluster configuration. This call is for internal use.\nnode string The cluster node name.\napiversion integer The JOIN_API_VERSION of the new node.\nforce boolean Do not throw error if node already exists.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnew_node_ip string IP Address of node to add. Used as fallback if no links are given.\nnodeid integer Node id for this node.\nvotes integer Number of votes for this node" + }, + { + "id": "GET /cluster/config/qdevice", + "method": "GET", + "path": "/cluster/config/qdevice", + "section": "cluster", + "summary": "status", + "description": "Get QDevice status", + "pathParameters": [], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "allowtoken": 1, + "description": "Get QDevice status", + "method": "GET", + "name": "status", + "parameters": { + "additionalProperties": 0 + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected": 1, + "returns": { + "type": "object" + } + }, + "searchText": "GET\n/cluster/config/qdevice\ncluster\nstatus\nGet QDevice status" + }, + { + "id": "GET /cluster/config/totem", + "method": "GET", + "path": "/cluster/config/totem", + "section": "cluster", + "summary": "totem", + "description": "Get corosync totem protocol settings.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "allowtoken": 1, + "description": "Get corosync totem protocol settings.", + "method": "GET", + "name": "totem", + "parameters": { + "additionalProperties": 0 + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns": { + "type": "object" + } + }, + "searchText": "GET\n/cluster/config/totem\ncluster\ntotem\nGet corosync totem protocol settings." + }, + { + "id": "GET /cluster/firewall", + "method": "GET", + "path": "/cluster/firewall", + "section": "cluster", + "summary": "index", + "description": "Directory index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall\ncluster\nindex\nDirectory index." + }, + { + "id": "GET /cluster/firewall/aliases", + "method": "GET", + "path": "/cluster/firewall/aliases", + "section": "cluster", + "summary": "get_aliases", + "description": "List aliases", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/aliases\ncluster\nget_aliases\nList aliases" + }, + { + "id": "POST /cluster/firewall/aliases", + "method": "POST", + "path": "/cluster/firewall/aliases", + "section": "cluster", + "summary": "create_alias", + "description": "Create IP or Network Alias.", + "pathParameters": [], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDR" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "comment", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/firewall/aliases\ncluster\ncreate_alias\nCreate IP or Network Alias.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string" + }, + { + "id": "DELETE /cluster/firewall/aliases/{name}", + "method": "DELETE", + "path": "/cluster/firewall/aliases/{name}", + "section": "cluster", + "summary": "remove_alias", + "description": "Remove IP or Network alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/firewall/aliases/{name}\ncluster\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/aliases/{name}", + "method": "GET", + "path": "/cluster/firewall/aliases/{name}", + "section": "cluster", + "summary": "read_alias", + "description": "Read alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/aliases/{name}\ncluster\nread_alias\nRead alias.\nname string Alias name." + }, + { + "id": "PUT /cluster/firewall/aliases/{name}", + "method": "PUT", + "path": "/cluster/firewall/aliases/{name}", + "section": "cluster", + "summary": "update_alias", + "description": "Update IP or Network alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDR" + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "rename", + "type": "string", + "required": false, + "description": "Rename an existing alias." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/firewall/aliases/{name}\ncluster\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias." + }, + { + "id": "GET /cluster/firewall/groups", + "method": "GET", + "path": "/cluster/firewall/groups", + "section": "cluster", + "summary": "list_security_groups", + "description": "List security groups.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/groups\ncluster\nlist_security_groups\nList security groups." + }, + { + "id": "POST /cluster/firewall/groups", + "method": "POST", + "path": "/cluster/firewall/groups", + "section": "cluster", + "summary": "create_security_group", + "description": "Create new security group.", + "pathParameters": [], + "requestParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "Security Group name." + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "rename", + "type": "string", + "required": false, + "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." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/firewall/groups\ncluster\ncreate_security_group\nCreate new security group.\ngroup string Security Group name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group." + }, + { + "id": "DELETE /cluster/firewall/groups/{group}", + "method": "DELETE", + "path": "/cluster/firewall/groups/{group}", + "section": "cluster", + "summary": "delete_security_group", + "description": "Delete security group.", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "Security Group name." + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/firewall/groups/{group}\ncluster\ndelete_security_group\nDelete security group.\ngroup string Security Group name." + }, + { + "id": "GET /cluster/firewall/groups/{group}", + "method": "GET", + "path": "/cluster/firewall/groups/{group}", + "section": "cluster", + "summary": "get_rules", + "description": "List rules.", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "Security Group name." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/groups/{group}\ncluster\nget_rules\nList rules.\ngroup string Security Group name." + }, + { + "id": "POST /cluster/firewall/groups/{group}", + "method": "POST", + "path": "/cluster/firewall/groups/{group}", + "section": "cluster", + "summary": "create_rule", + "description": "Create new rule.", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "Security Group name." + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/firewall/groups/{group}\ncluster\ncreate_rule\nCreate new rule.\ngroup string Security Group name.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /cluster/firewall/groups/{group}/{pos}", + "method": "DELETE", + "path": "/cluster/firewall/groups/{group}/{pos}", + "section": "cluster", + "summary": "delete_rule", + "description": "Delete rule.", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "Security Group name." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/firewall/groups/{group}/{pos}\ncluster\ndelete_rule\nDelete rule.\ngroup string Security Group name.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/groups/{group}/{pos}", + "method": "GET", + "path": "/cluster/firewall/groups/{group}/{pos}", + "section": "cluster", + "summary": "get_rule", + "description": "Get single rule data.", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "Security Group name." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/groups/{group}/{pos}\ncluster\nget_rule\nGet single rule data.\ngroup string Security Group name.\npos integer Update rule at position ." + }, + { + "id": "PUT /cluster/firewall/groups/{group}/{pos}", + "method": "PUT", + "path": "/cluster/firewall/groups/{group}/{pos}", + "section": "cluster", + "summary": "update_rule", + "description": "Modify rule data.", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "Security Group name." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "moveto", + "type": "integer", + "required": false, + "description": "Move rule to new position . Other arguments are ignored.", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/firewall/groups/{group}/{pos}\ncluster\nupdate_rule\nModify rule data.\ngroup string Security Group name.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "GET /cluster/firewall/ipset", + "method": "GET", + "path": "/cluster/firewall/ipset", + "section": "cluster", + "summary": "ipset_index", + "description": "List IPSets", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/ipset\ncluster\nipset_index\nList IPSets" + }, + { + "id": "POST /cluster/firewall/ipset", + "method": "POST", + "path": "/cluster/firewall/ipset", + "section": "cluster", + "summary": "create_ipset", + "description": "Create new IPSet", + "pathParameters": [], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "rename", + "type": "string", + "required": false, + "description": "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/firewall/ipset\ncluster\ncreate_ipset\nCreate new IPSet\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet." + }, + { + "id": "DELETE /cluster/firewall/ipset/{name}", + "method": "DELETE", + "path": "/cluster/firewall/ipset/{name}", + "section": "cluster", + "summary": "delete_ipset", + "description": "Delete IPSet", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Delete all members of the IPSet, if there are any." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/firewall/ipset/{name}\ncluster\ndelete_ipset\nDelete IPSet\nname string IP set name.\nforce boolean Delete all members of the IPSet, if there are any." + }, + { + "id": "GET /cluster/firewall/ipset/{name}", + "method": "GET", + "path": "/cluster/firewall/ipset/{name}", + "section": "cluster", + "summary": "get_ipset", + "description": "List IPSet content", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/ipset/{name}\ncluster\nget_ipset\nList IPSet content\nname string IP set name." + }, + { + "id": "POST /cluster/firewall/ipset/{name}", + "method": "POST", + "path": "/cluster/firewall/ipset/{name}", + "section": "cluster", + "summary": "create_ip", + "description": "Add IP or Network to IPSet.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "nomatch", + "type": "boolean", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/firewall/ipset/{name}\ncluster\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean" + }, + { + "id": "DELETE /cluster/firewall/ipset/{name}/{cidr}", + "method": "DELETE", + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "section": "cluster", + "summary": "remove_ip", + "description": "Remove IP or Network from IPSet.", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/ipset/{name}/{cidr}", + "method": "GET", + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "section": "cluster", + "summary": "read_ip", + "description": "Read IP or Network settings from IPSet.", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name." + }, + { + "id": "PUT /cluster/firewall/ipset/{name}/{cidr}", + "method": "PUT", + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "section": "cluster", + "summary": "update_ip", + "description": "Update IP or Network settings", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "nomatch", + "type": "boolean", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean" + }, + { + "id": "GET /cluster/firewall/macros", + "method": "GET", + "path": "/cluster/firewall/macros", + "section": "cluster", + "summary": "get_macros", + "description": "List available macros", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "descr": { + "description": "More verbose description (if available).", + "type": "string" + }, + "macro": { + "description": "Macro name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/macros\ncluster\nget_macros\nList available macros" + }, + { + "id": "GET /cluster/firewall/options", + "method": "GET", + "path": "/cluster/firewall/options", + "section": "cluster", + "summary": "get_options", + "description": "Get Firewall options.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/options\ncluster\nget_options\nGet Firewall options." + }, + { + "id": "PUT /cluster/firewall/options", + "method": "PUT", + "path": "/cluster/firewall/options", + "section": "cluster", + "summary": "set_options", + "description": "Set Firewall options.", + "pathParameters": [], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "ebtables", + "type": "boolean", + "required": false, + "description": "Enable ebtables rules cluster wide.", + "default": 1 + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Enable or disable the firewall cluster wide.", + "default": 0, + "minimum": 0 + }, + { + "name": "log_ratelimit", + "type": "string", + "required": false, + "description": "Log ratelimiting settings" + }, + { + "name": "policy_forward", + "type": "string", + "required": false, + "description": "Forward policy.", + "enum": [ + "ACCEPT", + "DROP" + ] + }, + { + "name": "policy_in", + "type": "string", + "required": false, + "description": "Input policy.", + "enum": [ + "ACCEPT", + "REJECT", + "DROP" + ] + }, + { + "name": "policy_out", + "type": "string", + "required": false, + "description": "Output policy.", + "enum": [ + "ACCEPT", + "REJECT", + "DROP" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/firewall/options\ncluster\nset_options\nSet Firewall options.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nebtables boolean Enable ebtables rules cluster wide.\nenable integer Enable or disable the firewall cluster wide.\nlog_ratelimit string Log ratelimiting settings\npolicy_forward string Forward policy. ACCEPT DROP\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP" + }, + { + "id": "GET /cluster/firewall/refs", + "method": "GET", + "path": "/cluster/firewall/refs", + "section": "cluster", + "summary": "refs", + "description": "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list references of specified type.", + "enum": [ + "alias", + "ipset" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/refs\ncluster\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\ntype string Only list references of specified type. alias ipset" + }, + { + "id": "GET /cluster/firewall/rules", + "method": "GET", + "path": "/cluster/firewall/rules", + "section": "cluster", + "summary": "get_rules", + "description": "List rules.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/rules\ncluster\nget_rules\nList rules." + }, + { + "id": "POST /cluster/firewall/rules", + "method": "POST", + "path": "/cluster/firewall/rules", + "section": "cluster", + "summary": "create_rule", + "description": "Create new rule.", + "pathParameters": [], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/firewall/rules\ncluster\ncreate_rule\nCreate new rule.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /cluster/firewall/rules/{pos}", + "method": "DELETE", + "path": "/cluster/firewall/rules/{pos}", + "section": "cluster", + "summary": "delete_rule", + "description": "Delete rule.", + "pathParameters": [ + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/firewall/rules/{pos}\ncluster\ndelete_rule\nDelete rule.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/rules/{pos}", + "method": "GET", + "path": "/cluster/firewall/rules/{pos}", + "section": "cluster", + "summary": "get_rule", + "description": "Get single rule data.", + "pathParameters": [ + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/firewall/rules/{pos}\ncluster\nget_rule\nGet single rule data.\npos integer Update rule at position ." + }, + { + "id": "PUT /cluster/firewall/rules/{pos}", + "method": "PUT", + "path": "/cluster/firewall/rules/{pos}", + "section": "cluster", + "summary": "update_rule", + "description": "Modify rule data.", + "pathParameters": [ + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "moveto", + "type": "integer", + "required": false, + "description": "Move rule to new position . Other arguments are ignored.", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/firewall/rules/{pos}\ncluster\nupdate_rule\nModify rule data.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "GET /cluster/ha", + "method": "GET", + "path": "/cluster/ha", + "section": "cluster", + "summary": "index", + "description": "Directory index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha\ncluster\nindex\nDirectory index." + }, + { + "id": "GET /cluster/ha/groups", + "method": "GET", + "path": "/cluster/ha/groups", + "section": "cluster", + "summary": "index", + "description": "Get HA groups. (deprecated in favor of HA rules)", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "group": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{group}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/groups\ncluster\nindex\nGet HA groups. (deprecated in favor of HA rules)" + }, + { + "id": "POST /cluster/ha/groups", + "method": "POST", + "path": "/cluster/ha/groups", + "section": "cluster", + "summary": "create", + "description": "Create a new HA group. (deprecated in favor of HA rules)", + "pathParameters": [], + "requestParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "The HA group identifier.", + "format": "pve-configid" + }, + { + "name": "nodes", + "type": "string", + "required": true, + "description": "List of cluster node names with optional priority.", + "format": "pve-ha-node-list" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "nofailback", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "restricted", + "type": "boolean", + "required": false, + "description": "Resources bound to restricted groups may only run on nodes defined by the group.", + "default": 0 + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Group type.", + "enum": [ + "group" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/ha/groups\ncluster\ncreate\nCreate a new HA group. (deprecated in favor of HA rules)\ngroup string The HA group identifier.\nnodes string List of cluster node names with optional priority.\ncomment string Description.\nnofailback boolean 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.\nrestricted boolean Resources bound to restricted groups may only run on nodes defined by the group.\ntype string Group type. group" + }, + { + "id": "DELETE /cluster/ha/groups/{group}", + "method": "DELETE", + "path": "/cluster/ha/groups/{group}", + "section": "cluster", + "summary": "delete", + "description": "Delete ha group configuration. (deprecated in favor of HA rules)", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "The HA group identifier.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/ha/groups/{group}\ncluster\ndelete\nDelete ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier." + }, + { + "id": "GET /cluster/ha/groups/{group}", + "method": "GET", + "path": "/cluster/ha/groups/{group}", + "section": "cluster", + "summary": "read", + "description": "Read ha group configuration. (deprecated in favor of HA rules)", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "The HA group identifier.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": {}, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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": {} + }, + "searchText": "GET\n/cluster/ha/groups/{group}\ncluster\nread\nRead ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier." + }, + { + "id": "PUT /cluster/ha/groups/{group}", + "method": "PUT", + "path": "/cluster/ha/groups/{group}", + "section": "cluster", + "summary": "update", + "description": "Update ha group configuration. (deprecated in favor of HA rules)", + "pathParameters": [ + { + "name": "group", + "type": "string", + "required": true, + "description": "The HA group identifier.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names with optional priority.", + "format": "pve-ha-node-list" + }, + { + "name": "nofailback", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "restricted", + "type": "boolean", + "required": false, + "description": "Resources bound to restricted groups may only run on nodes defined by the group.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/ha/groups/{group}\ncluster\nupdate\nUpdate ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier.\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnodes string List of cluster node names with optional priority.\nnofailback boolean 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.\nrestricted boolean Resources bound to restricted groups may only run on nodes defined by the group." + }, + { + "id": "GET /cluster/ha/resources", + "method": "GET", + "path": "/cluster/ha/resources", + "section": "cluster", + "summary": "index", + "description": "List HA resources.", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list resources of specific type", + "enum": [ + "ct", + "vm" + ] + } + ], + "returns": { + "items": { + "properties": { + "sid": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{sid}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/resources\ncluster\nindex\nList HA resources.\ntype string Only list resources of specific type ct vm" + }, + { + "id": "POST /cluster/ha/resources", + "method": "POST", + "path": "/cluster/ha/resources", + "section": "cluster", + "summary": "create", + "description": "Create a new HA resource.", + "pathParameters": [], + "requestParameters": [ + { + "name": "sid", + "type": "string", + "required": true, + "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" + }, + { + "name": "auto-rebalance", + "type": "boolean", + "required": false, + "description": "HA resource may be migrated during automatic rebalancing", + "default": 1 + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "failback", + "type": "boolean", + "required": false, + "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.", + "default": 1 + }, + { + "name": "group", + "type": "string", + "required": false, + "description": "The HA group identifier.", + "format": "pve-configid" + }, + { + "name": "max_relocate", + "type": "integer", + "required": false, + "description": "Maximal number of resource relocate tries when a resource fails to start.", + "default": 1, + "minimum": 0 + }, + { + "name": "max_restart", + "type": "integer", + "required": false, + "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.", + "default": 1, + "minimum": 0 + }, + { + "name": "state", + "type": "string", + "required": false, + "description": "Requested resource state.", + "enum": [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "default": "started" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Resource type.", + "enum": [ + "ct", + "vm" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/ha/resources\ncluster\ncreate\nCreate a new HA resource.\nsid string 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).\nauto-rebalance boolean HA resource may be migrated during automatic rebalancing\ncomment string Description.\nfailback boolean 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.\ngroup string The HA group identifier.\nmax_relocate integer Maximal number of resource relocate tries when a resource fails to start.\nmax_restart integer 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.\nstate string Requested resource state. started stopped enabled disabled ignored\ntype string Resource type. ct vm" + }, + { + "id": "DELETE /cluster/ha/resources/{sid}", + "method": "DELETE", + "path": "/cluster/ha/resources/{sid}", + "section": "cluster", + "summary": "delete", + "description": "Delete resource configuration.", + "pathParameters": [ + { + "name": "sid", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [ + { + "name": "purge", + "type": "boolean", + "required": false, + "description": "Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule", + "default": 1 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/ha/resources/{sid}\ncluster\ndelete\nDelete resource configuration.\nsid string 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).\npurge boolean Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule" + }, + { + "id": "GET /cluster/ha/resources/{sid}", + "method": "GET", + "path": "/cluster/ha/resources/{sid}", + "section": "cluster", + "summary": "read", + "description": "Read resource configuration.", + "pathParameters": [ + { + "name": "sid", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/resources/{sid}\ncluster\nread\nRead resource configuration.\nsid string 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)." + }, + { + "id": "PUT /cluster/ha/resources/{sid}", + "method": "PUT", + "path": "/cluster/ha/resources/{sid}", + "section": "cluster", + "summary": "update", + "description": "Update resource configuration.", + "pathParameters": [ + { + "name": "sid", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [ + { + "name": "auto-rebalance", + "type": "boolean", + "required": false, + "description": "HA resource may be migrated during automatic rebalancing", + "default": 1 + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "failback", + "type": "boolean", + "required": false, + "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.", + "default": 1 + }, + { + "name": "group", + "type": "string", + "required": false, + "description": "The HA group identifier.", + "format": "pve-configid" + }, + { + "name": "max_relocate", + "type": "integer", + "required": false, + "description": "Maximal number of resource relocate tries when a resource fails to start.", + "default": 1, + "minimum": 0 + }, + { + "name": "max_restart", + "type": "integer", + "required": false, + "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.", + "default": 1, + "minimum": 0 + }, + { + "name": "state", + "type": "string", + "required": false, + "description": "Requested resource state.", + "enum": [ + "started", + "stopped", + "enabled", + "disabled", + "ignored" + ], + "default": "started" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/ha/resources/{sid}\ncluster\nupdate\nUpdate resource configuration.\nsid string 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).\nauto-rebalance boolean HA resource may be migrated during automatic rebalancing\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfailback boolean 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.\ngroup string The HA group identifier.\nmax_relocate integer Maximal number of resource relocate tries when a resource fails to start.\nmax_restart integer 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.\nstate string Requested resource state. started stopped enabled disabled ignored" + }, + { + "id": "POST /cluster/ha/resources/{sid}/migrate", + "method": "POST", + "path": "/cluster/ha/resources/{sid}/migrate", + "section": "cluster", + "summary": "migrate", + "description": "Request resource migration (online) to another node.", + "pathParameters": [ + { + "name": "sid", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "Target node.", + "format": "pve-node" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/ha/resources/{sid}/migrate\ncluster\nmigrate\nRequest resource migration (online) to another node.\nsid string 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).\nnode string Target node." + }, + { + "id": "POST /cluster/ha/resources/{sid}/relocate", + "method": "POST", + "path": "/cluster/ha/resources/{sid}/relocate", + "section": "cluster", + "summary": "relocate", + "description": "Request resource relocation to another node. This stops the service on the old node, and restarts it on the target node.", + "pathParameters": [ + { + "name": "sid", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "Target node.", + "format": "pve-node" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/ha/resources/{sid}/relocate\ncluster\nrelocate\nRequest resource relocation to another node. This stops the service on the old node, and restarts it on the target node.\nsid string 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).\nnode string Target node." + }, + { + "id": "GET /cluster/ha/rules", + "method": "GET", + "path": "/cluster/ha/rules", + "section": "cluster", + "summary": "index", + "description": "Get HA rules.", + "pathParameters": [], + "requestParameters": [ + { + "name": "resource", + "type": "string", + "required": false, + "description": "Limit the returned list to rules affecting the specified resource." + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Limit the returned list to the specified rule type.", + "enum": [ + "node-affinity", + "resource-affinity" + ] + } + ], + "returns": { + "items": { + "links": [ + { + "href": "{rule}", + "rel": "child" + } + ], + "properties": { + "rule": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/rules\ncluster\nindex\nGet HA rules.\nresource string Limit the returned list to rules affecting the specified resource.\ntype string Limit the returned list to the specified rule type. node-affinity resource-affinity" + }, + { + "id": "POST /cluster/ha/rules", + "method": "POST", + "path": "/cluster/ha/rules", + "section": "cluster", + "summary": "create_rule", + "description": "Create HA rule.", + "pathParameters": [], + "requestParameters": [ + { + "name": "resources", + "type": "string", + "required": true, + "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" + }, + { + "name": "rule", + "type": "string", + "required": true, + "description": "HA rule identifier.", + "format": "pve-configid" + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "HA rule type.", + "enum": [ + "node-affinity", + "resource-affinity" + ] + }, + { + "name": "affinity", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "HA rule description." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Whether the HA rule is disabled." + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names with optional priority.", + "format": "pve-ha-node-list" + }, + { + "name": "strict", + "type": "boolean", + "required": false, + "description": "Describes whether the node affinity rule is strict or non-strict.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/ha/rules\ncluster\ncreate_rule\nCreate HA rule.\nresources string 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).\nrule string HA rule identifier.\ntype string HA rule type. node-affinity resource-affinity\naffinity string 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'). positive negative\ncomment string HA rule description.\ndisable boolean Whether the HA rule is disabled.\nnodes string List of cluster node names with optional priority.\nstrict boolean Describes whether the node affinity rule is strict or non-strict." + }, + { + "id": "DELETE /cluster/ha/rules/{rule}", + "method": "DELETE", + "path": "/cluster/ha/rules/{rule}", + "section": "cluster", + "summary": "delete_rule", + "description": "Delete HA rule.", + "pathParameters": [ + { + "name": "rule", + "type": "string", + "required": true, + "description": "HA rule identifier.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/ha/rules/{rule}\ncluster\ndelete_rule\nDelete HA rule.\nrule string HA rule identifier." + }, + { + "id": "GET /cluster/ha/rules/{rule}", + "method": "GET", + "path": "/cluster/ha/rules/{rule}", + "section": "cluster", + "summary": "read_rule", + "description": "Read HA rule.", + "pathParameters": [ + { + "name": "rule", + "type": "string", + "required": true, + "description": "HA rule identifier.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/rules/{rule}\ncluster\nread_rule\nRead HA rule.\nrule string HA rule identifier." + }, + { + "id": "PUT /cluster/ha/rules/{rule}", + "method": "PUT", + "path": "/cluster/ha/rules/{rule}", + "section": "cluster", + "summary": "update_rule", + "description": "Update HA rule.", + "pathParameters": [ + { + "name": "rule", + "type": "string", + "required": true, + "description": "HA rule identifier.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": true, + "description": "HA rule type.", + "enum": [ + "node-affinity", + "resource-affinity" + ] + }, + { + "name": "affinity", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "HA rule description." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Whether the HA rule is disabled." + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names with optional priority.", + "format": "pve-ha-node-list" + }, + { + "name": "resources", + "type": "string", + "required": false, + "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" + }, + { + "name": "strict", + "type": "boolean", + "required": false, + "description": "Describes whether the node affinity rule is strict or non-strict.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/ha/rules/{rule}\ncluster\nupdate_rule\nUpdate HA rule.\nrule string HA rule identifier.\ntype string HA rule type. node-affinity resource-affinity\naffinity string 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'). positive negative\ncomment string HA rule description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Whether the HA rule is disabled.\nnodes string List of cluster node names with optional priority.\nresources string 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).\nstrict boolean Describes whether the node affinity rule is strict or non-strict." + }, + { + "id": "GET /cluster/ha/status", + "method": "GET", + "path": "/cluster/ha/status", + "section": "cluster", + "summary": "index", + "description": "Directory index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/status\ncluster\nindex\nDirectory index." + }, + { + "id": "POST /cluster/ha/status/arm-ha", + "method": "POST", + "path": "/cluster/ha/status/arm-ha", + "section": "cluster", + "summary": "arm-ha", + "description": "Request re-arming the HA stack after it was disarmed.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/ha/status/arm-ha\ncluster\narm-ha\nRequest re-arming the HA stack after it was disarmed." + }, + { + "id": "GET /cluster/ha/status/current", + "method": "GET", + "path": "/cluster/ha/status/current", + "section": "cluster", + "summary": "status", + "description": "Get HA manager status.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/status/current\ncluster\nstatus\nGet HA manager status." + }, + { + "id": "POST /cluster/ha/status/disarm-ha", + "method": "POST", + "path": "/cluster/ha/status/disarm-ha", + "section": "cluster", + "summary": "disarm-ha", + "description": "Request disarming the HA stack, releasing all watchdogs cluster-wide.", + "pathParameters": [], + "requestParameters": [ + { + "name": "resource-mode", + "type": "string", + "required": true, + "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" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/ha/status/disarm-ha\ncluster\ndisarm-ha\nRequest disarming the HA stack, releasing all watchdogs cluster-wide.\nresource-mode string 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. freeze ignore" + }, + { + "id": "GET /cluster/ha/status/manager_status", + "method": "GET", + "path": "/cluster/ha/status/manager_status", + "section": "cluster", + "summary": "manager_status", + "description": "Get full HA manager status, including LRM status.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/ha/status/manager_status\ncluster\nmanager_status\nGet full HA manager status, including LRM status." + }, + { + "id": "GET /cluster/jobs", + "method": "GET", + "path": "/cluster/jobs", + "section": "cluster", + "summary": "index", + "description": "Index for jobs related endpoints.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "description": "Directory index.", + "items": { + "properties": { + "subdir": { + "description": "API sub-directory endpoint", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/jobs\ncluster\nindex\nIndex for jobs related endpoints." + }, + { + "id": "GET /cluster/jobs/realm-sync", + "method": "GET", + "path": "/cluster/jobs/realm-sync", + "section": "cluster", + "summary": "syncjob_index", + "description": "List configured realm-sync-jobs.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/jobs/realm-sync\ncluster\nsyncjob_index\nList configured realm-sync-jobs." + }, + { + "id": "DELETE /cluster/jobs/realm-sync/{id}", + "method": "DELETE", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "delete_job", + "description": "Delete realm-sync job definition.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/jobs/realm-sync/{id}\ncluster\ndelete_job\nDelete realm-sync job definition.\nid string" + }, + { + "id": "GET /cluster/jobs/realm-sync/{id}", + "method": "GET", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "read_job", + "description": "Read realm-sync job definition.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/jobs/realm-sync/{id}\ncluster\nread_job\nRead realm-sync job definition.\nid string" + }, + { + "id": "POST /cluster/jobs/realm-sync/{id}", + "method": "POST", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "create_job", + "description": "Create new realm-sync job.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the job.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "schedule", + "type": "string", + "required": true, + "description": "Backup schedule. The format is a subset of `systemd` calendar events.", + "format": "pve-calendar-event" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description for the Job." + }, + { + "name": "enable-new", + "type": "boolean", + "required": false, + "description": "Enable newly synced users immediately.", + "default": "1" + }, + { + "name": "enabled", + "type": "boolean", + "required": false, + "description": "Determines if the job is enabled.", + "default": 1 + }, + { + "name": "realm", + "type": "string", + "required": false, + "description": "Authentication domain ID", + "format": "pve-realm" + }, + { + "name": "remove-vanished", + "type": "string", + "required": false, + "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).", + "default": "none" + }, + { + "name": "scope", + "type": "string", + "required": false, + "description": "Select what to sync.", + "enum": [ + "users", + "groups", + "both" + ] + } + ], + "returns": { + "type": "null" + }, + "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/'." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/jobs/realm-sync/{id}\ncluster\ncreate_job\nCreate new realm-sync job.\nid string The ID of the job.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\ncomment string Description for the Job.\nenable-new boolean Enable newly synced users immediately.\nenabled boolean Determines if the job is enabled.\nrealm string Authentication domain ID\nremove-vanished string 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).\nscope string Select what to sync. users groups both" + }, + { + "id": "PUT /cluster/jobs/realm-sync/{id}", + "method": "PUT", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "update_job", + "description": "Update realm-sync job definition.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the job.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "schedule", + "type": "string", + "required": true, + "description": "Backup schedule. The format is a subset of `systemd` calendar events.", + "format": "pve-calendar-event" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description for the Job." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "enable-new", + "type": "boolean", + "required": false, + "description": "Enable newly synced users immediately.", + "default": "1" + }, + { + "name": "enabled", + "type": "boolean", + "required": false, + "description": "Determines if the job is enabled.", + "default": 1 + }, + { + "name": "remove-vanished", + "type": "string", + "required": false, + "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).", + "default": "none" + }, + { + "name": "scope", + "type": "string", + "required": false, + "description": "Select what to sync.", + "enum": [ + "users", + "groups", + "both" + ] + } + ], + "returns": { + "type": "null" + }, + "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/'." + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/jobs/realm-sync/{id}\ncluster\nupdate_job\nUpdate realm-sync job definition.\nid string The ID of the job.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\ncomment string Description for the Job.\ndelete string A list of settings you want to delete.\nenable-new boolean Enable newly synced users immediately.\nenabled boolean Determines if the job is enabled.\nremove-vanished string 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).\nscope string Select what to sync. users groups both" + }, + { + "id": "GET /cluster/jobs/schedule-analyze", + "method": "GET", + "path": "/cluster/jobs/schedule-analyze", + "section": "cluster", + "summary": "schedule-analyze", + "description": "Returns a list of future schedule runtimes.", + "pathParameters": [], + "requestParameters": [ + { + "name": "schedule", + "type": "string", + "required": true, + "description": "Job schedule. The format is a subset of `systemd` calendar events.", + "format": "pve-calendar-event" + }, + { + "name": "iterations", + "type": "integer", + "required": false, + "description": "Number of event-iteration to simulate and return.", + "default": 10, + "minimum": 1, + "maximum": 100 + }, + { + "name": "starttime", + "type": "integer", + "required": false, + "description": "UNIX timestamp to start the calculation from. Defaults to the current time." + } + ], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/jobs/schedule-analyze\ncluster\nschedule-analyze\nReturns a list of future schedule runtimes.\nschedule string Job schedule. The format is a subset of `systemd` calendar events.\niterations integer Number of event-iteration to simulate and return.\nstarttime integer UNIX timestamp to start the calculation from. Defaults to the current time." + }, + { + "id": "GET /cluster/log", + "method": "GET", + "path": "/cluster/log", + "section": "cluster", + "summary": "log", + "description": "Read cluster log", + "pathParameters": [], + "requestParameters": [ + { + "name": "max", + "type": "integer", + "required": false, + "description": "Maximum number of entries.", + "minimum": 1 + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "description": "The user needs 'Sys.Syslog' on '/' in order to get all logs.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/log\ncluster\nlog\nRead cluster log\nmax integer Maximum number of entries." + }, + { + "id": "GET /cluster/mapping", + "method": "GET", + "path": "/cluster/mapping", + "section": "cluster", + "summary": "index", + "description": "List resource types.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/mapping\ncluster\nindex\nList resource types." + }, + { + "id": "GET /cluster/mapping/dir", + "method": "GET", + "path": "/cluster/mapping/dir", + "section": "cluster", + "summary": "index", + "description": "List directory mapping", + "pathParameters": [], + "requestParameters": [ + { + "name": "check-node", + "type": "string", + "required": false, + "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" + } + ], + "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" + }, + "permissions": { + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/mapping/dir\ncluster\nindex\nList directory mapping\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response." + }, + { + "id": "POST /cluster/mapping/dir", + "method": "POST", + "path": "/cluster/mapping/dir", + "section": "cluster", + "summary": "create", + "description": "Create a new directory mapping.", + "pathParameters": [], + "requestParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the directory mapping", + "format": "pve-configid" + }, + { + "name": "map", + "type": "array", + "required": true, + "description": "A list of maps for the cluster nodes." + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description of the directory mapping" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/mapping/dir\ncluster\ncreate\nCreate a new directory mapping.\nid string The ID of the directory mapping\nmap array A list of maps for the cluster nodes.\ndescription string Description of the directory mapping" + }, + { + "id": "DELETE /cluster/mapping/dir/{id}", + "method": "DELETE", + "path": "/cluster/mapping/dir/{id}", + "section": "cluster", + "summary": "delete", + "description": "Remove directory mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/mapping/dir/{id}\ncluster\ndelete\nRemove directory mapping.\nid string" + }, + { + "id": "GET /cluster/mapping/dir/{id}", + "method": "GET", + "path": "/cluster/mapping/dir/{id}", + "section": "cluster", + "summary": "get", + "description": "Get directory mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/mapping/dir/{id}\ncluster\nget\nGet directory mapping.\nid string" + }, + { + "id": "PUT /cluster/mapping/dir/{id}", + "method": "PUT", + "path": "/cluster/mapping/dir/{id}", + "section": "cluster", + "summary": "update", + "description": "Update a directory mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the directory mapping", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description of the directory mapping" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "map", + "type": "array", + "required": false, + "description": "A list of maps for the cluster nodes." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/mapping/dir/{id}\ncluster\nupdate\nUpdate a directory mapping.\nid string The ID of the directory mapping\ndelete string A list of settings you want to delete.\ndescription string Description of the directory mapping\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nmap array A list of maps for the cluster nodes." + }, + { + "id": "GET /cluster/mapping/pci", + "method": "GET", + "path": "/cluster/mapping/pci", + "section": "cluster", + "summary": "index", + "description": "List PCI Hardware Mapping", + "pathParameters": [], + "requestParameters": [ + { + "name": "check-node", + "type": "string", + "required": false, + "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" + } + ], + "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" + }, + "permissions": { + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/mapping/pci\ncluster\nindex\nList PCI Hardware Mapping\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response." + }, + { + "id": "POST /cluster/mapping/pci", + "method": "POST", + "path": "/cluster/mapping/pci", + "section": "cluster", + "summary": "create", + "description": "Create a new hardware mapping.", + "pathParameters": [], + "requestParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the logical PCI mapping.", + "format": "pve-configid" + }, + { + "name": "map", + "type": "array", + "required": true, + "description": "A list of maps for the cluster nodes." + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description of the logical PCI device." + }, + { + "name": "live-migration-capable", + "type": "boolean", + "required": false, + "description": "Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.", + "default": 0 + }, + { + "name": "mdev", + "type": "boolean", + "required": false, + "description": "Marks the device(s) as being capable of providing mediated devices.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/mapping/pci\ncluster\ncreate\nCreate a new hardware mapping.\nid string The ID of the logical PCI mapping.\nmap array A list of maps for the cluster nodes.\ndescription string Description of the logical PCI device.\nlive-migration-capable boolean Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.\nmdev boolean Marks the device(s) as being capable of providing mediated devices." + }, + { + "id": "DELETE /cluster/mapping/pci/{id}", + "method": "DELETE", + "path": "/cluster/mapping/pci/{id}", + "section": "cluster", + "summary": "delete", + "description": "Remove Hardware Mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/mapping/pci/{id}\ncluster\ndelete\nRemove Hardware Mapping.\nid string" + }, + { + "id": "GET /cluster/mapping/pci/{id}", + "method": "GET", + "path": "/cluster/mapping/pci/{id}", + "section": "cluster", + "summary": "get", + "description": "Get PCI Mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/mapping/pci/{id}\ncluster\nget\nGet PCI Mapping.\nid string" + }, + { + "id": "PUT /cluster/mapping/pci/{id}", + "method": "PUT", + "path": "/cluster/mapping/pci/{id}", + "section": "cluster", + "summary": "update", + "description": "Update a hardware mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the logical PCI mapping.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description of the logical PCI device." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "live-migration-capable", + "type": "boolean", + "required": false, + "description": "Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.", + "default": 0 + }, + { + "name": "map", + "type": "array", + "required": false, + "description": "A list of maps for the cluster nodes." + }, + { + "name": "mdev", + "type": "boolean", + "required": false, + "description": "Marks the device(s) as being capable of providing mediated devices.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/mapping/pci/{id}\ncluster\nupdate\nUpdate a hardware mapping.\nid string The ID of the logical PCI mapping.\ndelete string A list of settings you want to delete.\ndescription string Description of the logical PCI device.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nlive-migration-capable boolean Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.\nmap array A list of maps for the cluster nodes.\nmdev boolean Marks the device(s) as being capable of providing mediated devices." + }, + { + "id": "GET /cluster/mapping/usb", + "method": "GET", + "path": "/cluster/mapping/usb", + "section": "cluster", + "summary": "index", + "description": "List USB Hardware Mappings", + "pathParameters": [], + "requestParameters": [ + { + "name": "check-node", + "type": "string", + "required": false, + "description": "If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices.", + "format": "pve-node" + } + ], + "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" + }, + "permissions": { + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/mapping/usb\ncluster\nindex\nList USB Hardware Mappings\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices." + }, + { + "id": "POST /cluster/mapping/usb", + "method": "POST", + "path": "/cluster/mapping/usb", + "section": "cluster", + "summary": "create", + "description": "Create a new hardware mapping.", + "pathParameters": [], + "requestParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the logical USB mapping.", + "format": "pve-configid" + }, + { + "name": "map", + "type": "array", + "required": true, + "description": "A list of maps for the cluster nodes." + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description of the logical USB device." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/mapping/usb\ncluster\ncreate\nCreate a new hardware mapping.\nid string The ID of the logical USB mapping.\nmap array A list of maps for the cluster nodes.\ndescription string Description of the logical USB device." + }, + { + "id": "DELETE /cluster/mapping/usb/{id}", + "method": "DELETE", + "path": "/cluster/mapping/usb/{id}", + "section": "cluster", + "summary": "delete", + "description": "Remove Hardware Mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/mapping/usb/{id}\ncluster\ndelete\nRemove Hardware Mapping.\nid string" + }, + { + "id": "GET /cluster/mapping/usb/{id}", + "method": "GET", + "path": "/cluster/mapping/usb/{id}", + "section": "cluster", + "summary": "get", + "description": "Get USB Mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/mapping/usb/{id}\ncluster\nget\nGet USB Mapping.\nid string" + }, + { + "id": "PUT /cluster/mapping/usb/{id}", + "method": "PUT", + "path": "/cluster/mapping/usb/{id}", + "section": "cluster", + "summary": "update", + "description": "Update a hardware mapping.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the logical USB mapping.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "map", + "type": "array", + "required": true, + "description": "A list of maps for the cluster nodes." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description of the logical USB device." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/mapping/usb/{id}\ncluster\nupdate\nUpdate a hardware mapping.\nid string The ID of the logical USB mapping.\nmap array A list of maps for the cluster nodes.\ndelete string A list of settings you want to delete.\ndescription string Description of the logical USB device.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/metrics", + "method": "GET", + "path": "/cluster/metrics", + "section": "cluster", + "summary": "index", + "description": "Metrics index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/metrics\ncluster\nindex\nMetrics index." + }, + { + "id": "GET /cluster/metrics/export", + "method": "GET", + "path": "/cluster/metrics/export", + "section": "cluster", + "summary": "export", + "description": "Retrieve metrics of the cluster.", + "pathParameters": [], + "requestParameters": [ + { + "name": "history", + "type": "boolean", + "required": false, + "description": "Also return historic values. Returns full available metric history unless `start-time` is also set", + "default": 0 + }, + { + "name": "local-only", + "type": "boolean", + "required": false, + "description": "Only return metrics for the current node instead of the whole cluster", + "default": 0 + }, + { + "name": "node-list", + "type": "string", + "required": false, + "description": "Only return metrics from nodes passed as comma-separated list" + }, + { + "name": "start-time", + "type": "integer", + "required": false, + "description": "Only include metrics with a timestamp > start-time.", + "default": 0 + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/metrics/export\ncluster\nexport\nRetrieve metrics of the cluster.\nhistory boolean Also return historic values. Returns full available metric history unless `start-time` is also set\nlocal-only boolean Only return metrics for the current node instead of the whole cluster\nnode-list string Only return metrics from nodes passed as comma-separated list\nstart-time integer Only include metrics with a timestamp > start-time." + }, + { + "id": "GET /cluster/metrics/server", + "method": "GET", + "path": "/cluster/metrics/server", + "section": "cluster", + "summary": "server_index", + "description": "List configured metric servers.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/metrics/server\ncluster\nserver_index\nList configured metric servers." + }, + { + "id": "DELETE /cluster/metrics/server/{id}", + "method": "DELETE", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "delete", + "description": "Remove Metric server.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/metrics/server/{id}\ncluster\ndelete\nRemove Metric server.\nid string" + }, + { + "id": "GET /cluster/metrics/server/{id}", + "method": "GET", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "read", + "description": "Read metric server configuration.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/metrics/server/{id}\ncluster\nread\nRead metric server configuration.\nid string" + }, + { + "id": "POST /cluster/metrics/server/{id}", + "method": "POST", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "create", + "description": "Create a new external metric server config", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the entry.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "port", + "type": "integer", + "required": true, + "description": "server network port", + "minimum": 1, + "maximum": 65536 + }, + { + "name": "server", + "type": "string", + "required": true, + "description": "server dns name or IP address", + "format": "address" + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Plugin type.", + "enum": [ + "graphite", + "influxdb", + "opentelemetry" + ], + "format": "pve-configid" + }, + { + "name": "api-path-prefix", + "type": "string", + "required": false, + "description": "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy." + }, + { + "name": "bucket", + "type": "string", + "required": false, + "description": "The InfluxDB bucket/db. Only necessary when using the http v2 api." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable the plugin." + }, + { + "name": "influxdbproto", + "type": "string", + "required": false, + "enum": [ + "udp", + "http", + "https" + ], + "default": "udp" + }, + { + "name": "max-body-size", + "type": "integer", + "required": false, + "description": "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "default": 25000000, + "minimum": 1 + }, + { + "name": "mtu", + "type": "integer", + "required": false, + "description": "MTU for metrics transmission over UDP", + "default": 1500, + "minimum": 512, + "maximum": 65536 + }, + { + "name": "organization", + "type": "string", + "required": false, + "description": "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api." + }, + { + "name": "otel-compression", + "type": "string", + "required": false, + "description": "Compression algorithm for requests", + "enum": [ + "none", + "gzip" + ], + "default": "gzip" + }, + { + "name": "otel-headers", + "type": "string", + "required": false, + "description": "Custom HTTP headers (JSON format, base64 encoded)" + }, + { + "name": "otel-max-body-size", + "type": "integer", + "required": false, + "description": "Maximum request body size in bytes", + "default": 10000000, + "minimum": 1024 + }, + { + "name": "otel-path", + "type": "string", + "required": false, + "description": "OTLP endpoint path", + "default": "/v1/metrics" + }, + { + "name": "otel-protocol", + "type": "string", + "required": false, + "description": "HTTP protocol", + "enum": [ + "http", + "https" + ], + "default": "https" + }, + { + "name": "otel-resource-attributes", + "type": "string", + "required": false, + "description": "Additional resource attributes as JSON, base64 encoded" + }, + { + "name": "otel-timeout", + "type": "integer", + "required": false, + "description": "HTTP request timeout in seconds", + "default": 5, + "minimum": 1, + "maximum": 10 + }, + { + "name": "otel-verify-ssl", + "type": "boolean", + "required": false, + "description": "Verify SSL certificates", + "default": 1 + }, + { + "name": "path", + "type": "string", + "required": false, + "description": "root graphite path (ex: proxmox.mycluster.mykey)", + "format": "graphite-path" + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "Protocol to send graphite data. TCP or UDP (default)", + "enum": [ + "udp", + "tcp" + ] + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "graphite TCP socket timeout (default=1)", + "default": 1, + "minimum": 0 + }, + { + "name": "token", + "type": "string", + "required": false, + "description": "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead." + }, + { + "name": "verify-certificate", + "type": "boolean", + "required": false, + "description": "Set to 0 to disable certificate verification for https endpoints.", + "default": 1 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/metrics/server/{id}\ncluster\ncreate\nCreate a new external metric server config\nid string The ID of the entry.\nport integer server network port\nserver string server dns name or IP address\ntype string Plugin type. graphite influxdb opentelemetry\napi-path-prefix string An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.\nbucket string The InfluxDB bucket/db. Only necessary when using the http v2 api.\ndisable boolean Flag to disable the plugin.\ninfluxdbproto string udp http https\nmax-body-size integer InfluxDB max-body-size in bytes. Requests are batched up to this size.\nmtu integer MTU for metrics transmission over UDP\norganization string The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.\notel-compression string Compression algorithm for requests none gzip\notel-headers string Custom HTTP headers (JSON format, base64 encoded)\notel-max-body-size integer Maximum request body size in bytes\notel-path string OTLP endpoint path\notel-protocol string HTTP protocol http https\notel-resource-attributes string Additional resource attributes as JSON, base64 encoded\notel-timeout integer HTTP request timeout in seconds\notel-verify-ssl boolean Verify SSL certificates\npath string root graphite path (ex: proxmox.mycluster.mykey)\nproto string Protocol to send graphite data. TCP or UDP (default) udp tcp\ntimeout integer graphite TCP socket timeout (default=1)\ntoken string The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.\nverify-certificate boolean Set to 0 to disable certificate verification for https endpoints." + }, + { + "id": "PUT /cluster/metrics/server/{id}", + "method": "PUT", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "update", + "description": "Update metric server configuration.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the entry.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "port", + "type": "integer", + "required": true, + "description": "server network port", + "minimum": 1, + "maximum": 65536 + }, + { + "name": "server", + "type": "string", + "required": true, + "description": "server dns name or IP address", + "format": "address" + }, + { + "name": "api-path-prefix", + "type": "string", + "required": false, + "description": "An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy." + }, + { + "name": "bucket", + "type": "string", + "required": false, + "description": "The InfluxDB bucket/db. Only necessary when using the http v2 api." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable the plugin." + }, + { + "name": "influxdbproto", + "type": "string", + "required": false, + "enum": [ + "udp", + "http", + "https" + ], + "default": "udp" + }, + { + "name": "max-body-size", + "type": "integer", + "required": false, + "description": "InfluxDB max-body-size in bytes. Requests are batched up to this size.", + "default": 25000000, + "minimum": 1 + }, + { + "name": "mtu", + "type": "integer", + "required": false, + "description": "MTU for metrics transmission over UDP", + "default": 1500, + "minimum": 512, + "maximum": 65536 + }, + { + "name": "organization", + "type": "string", + "required": false, + "description": "The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api." + }, + { + "name": "otel-compression", + "type": "string", + "required": false, + "description": "Compression algorithm for requests", + "enum": [ + "none", + "gzip" + ], + "default": "gzip" + }, + { + "name": "otel-headers", + "type": "string", + "required": false, + "description": "Custom HTTP headers (JSON format, base64 encoded)" + }, + { + "name": "otel-max-body-size", + "type": "integer", + "required": false, + "description": "Maximum request body size in bytes", + "default": 10000000, + "minimum": 1024 + }, + { + "name": "otel-path", + "type": "string", + "required": false, + "description": "OTLP endpoint path", + "default": "/v1/metrics" + }, + { + "name": "otel-protocol", + "type": "string", + "required": false, + "description": "HTTP protocol", + "enum": [ + "http", + "https" + ], + "default": "https" + }, + { + "name": "otel-resource-attributes", + "type": "string", + "required": false, + "description": "Additional resource attributes as JSON, base64 encoded" + }, + { + "name": "otel-timeout", + "type": "integer", + "required": false, + "description": "HTTP request timeout in seconds", + "default": 5, + "minimum": 1, + "maximum": 10 + }, + { + "name": "otel-verify-ssl", + "type": "boolean", + "required": false, + "description": "Verify SSL certificates", + "default": 1 + }, + { + "name": "path", + "type": "string", + "required": false, + "description": "root graphite path (ex: proxmox.mycluster.mykey)", + "format": "graphite-path" + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "Protocol to send graphite data. TCP or UDP (default)", + "enum": [ + "udp", + "tcp" + ] + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "graphite TCP socket timeout (default=1)", + "default": 1, + "minimum": 0 + }, + { + "name": "token", + "type": "string", + "required": false, + "description": "The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead." + }, + { + "name": "verify-certificate", + "type": "boolean", + "required": false, + "description": "Set to 0 to disable certificate verification for https endpoints.", + "default": 1 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/metrics/server/{id}\ncluster\nupdate\nUpdate metric server configuration.\nid string The ID of the entry.\nport integer server network port\nserver string server dns name or IP address\napi-path-prefix string An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.\nbucket string The InfluxDB bucket/db. Only necessary when using the http v2 api.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the plugin.\ninfluxdbproto string udp http https\nmax-body-size integer InfluxDB max-body-size in bytes. Requests are batched up to this size.\nmtu integer MTU for metrics transmission over UDP\norganization string The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.\notel-compression string Compression algorithm for requests none gzip\notel-headers string Custom HTTP headers (JSON format, base64 encoded)\notel-max-body-size integer Maximum request body size in bytes\notel-path string OTLP endpoint path\notel-protocol string HTTP protocol http https\notel-resource-attributes string Additional resource attributes as JSON, base64 encoded\notel-timeout integer HTTP request timeout in seconds\notel-verify-ssl boolean Verify SSL certificates\npath string root graphite path (ex: proxmox.mycluster.mykey)\nproto string Protocol to send graphite data. TCP or UDP (default) udp tcp\ntimeout integer graphite TCP socket timeout (default=1)\ntoken string The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.\nverify-certificate boolean Set to 0 to disable certificate verification for https endpoints." + }, + { + "id": "GET /cluster/nextid", + "method": "GET", + "path": "/cluster/nextid", + "section": "cluster", + "summary": "nextid", + "description": "Get next free VMID. Pass a VMID to assert that its free (at time of check).", + "pathParameters": [], + "requestParameters": [ + { + "name": "vmid", + "type": "integer", + "required": false, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "returns": { + "description": "The next free VMID.", + "type": "integer" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/nextid\ncluster\nnextid\nGet next free VMID. Pass a VMID to assert that its free (at time of check).\nvmid integer The (unique) ID of the VM." + }, + { + "id": "GET /cluster/notifications", + "method": "GET", + "path": "/cluster/notifications", + "section": "cluster", + "summary": "index", + "description": "Index for notification-related API endpoints.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications\ncluster\nindex\nIndex for notification-related API endpoints." + }, + { + "id": "GET /cluster/notifications/endpoints", + "method": "GET", + "path": "/cluster/notifications/endpoints", + "section": "cluster", + "summary": "endpoints_index", + "description": "Index for all available endpoint types.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints\ncluster\nendpoints_index\nIndex for all available endpoint types." + }, + { + "id": "GET /cluster/notifications/endpoints/gotify", + "method": "GET", + "path": "/cluster/notifications/endpoints/gotify", + "section": "cluster", + "summary": "get_gotify_endpoints", + "description": "Returns a list of all gotify endpoints", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/gotify\ncluster\nget_gotify_endpoints\nReturns a list of all gotify endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/gotify", + "method": "POST", + "path": "/cluster/notifications/endpoints/gotify", + "section": "cluster", + "summary": "create_gotify_endpoint", + "description": "Create a new gotify endpoint", + "pathParameters": [], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + }, + { + "name": "server", + "type": "string", + "required": true, + "description": "Server URL" + }, + { + "name": "token", + "type": "string", + "required": true, + "description": "Secret token" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/notifications/endpoints/gotify\ncluster\ncreate_gotify_endpoint\nCreate a new gotify endpoint\nname string The name of the endpoint.\nserver string Server URL\ntoken string Secret token\ncomment string Comment\ndisable boolean Disable this target" + }, + { + "id": "DELETE /cluster/notifications/endpoints/gotify/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/gotify/{name}", + "section": "cluster", + "summary": "delete_gotify_endpoint", + "description": "Remove gotify endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/notifications/endpoints/gotify/{name}\ncluster\ndelete_gotify_endpoint\nRemove gotify endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/gotify/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/gotify/{name}", + "section": "cluster", + "summary": "get_gotify_endpoint", + "description": "Return a specific gotify endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Name of the endpoint.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/gotify/{name}\ncluster\nget_gotify_endpoint\nReturn a specific gotify endpoint\nname string Name of the endpoint." + }, + { + "id": "PUT /cluster/notifications/endpoints/gotify/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/gotify/{name}", + "section": "cluster", + "summary": "update_gotify_endpoint", + "description": "Update existing gotify endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "delete", + "type": "array", + "required": false, + "description": "A list of settings you want to delete." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + }, + { + "name": "server", + "type": "string", + "required": false, + "description": "Server URL" + }, + { + "name": "token", + "type": "string", + "required": false, + "description": "Secret token" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/notifications/endpoints/gotify/{name}\ncluster\nupdate_gotify_endpoint\nUpdate existing gotify endpoint\nname string The name of the endpoint.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nserver string Server URL\ntoken string Secret token" + }, + { + "id": "GET /cluster/notifications/endpoints/sendmail", + "method": "GET", + "path": "/cluster/notifications/endpoints/sendmail", + "section": "cluster", + "summary": "get_sendmail_endpoints", + "description": "Returns a list of all sendmail endpoints", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/sendmail\ncluster\nget_sendmail_endpoints\nReturns a list of all sendmail endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/sendmail", + "method": "POST", + "path": "/cluster/notifications/endpoints/sendmail", + "section": "cluster", + "summary": "create_sendmail_endpoint", + "description": "Create a new sendmail endpoint", + "pathParameters": [], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + }, + { + "name": "author", + "type": "string", + "required": false, + "description": "Author of the mail" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + }, + { + "name": "from-address", + "type": "string", + "required": false, + "description": "`From` address for the mail" + }, + { + "name": "mailto", + "type": "array", + "required": false, + "description": "List of email recipients" + }, + { + "name": "mailto-user", + "type": "array", + "required": false, + "description": "List of users" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/notifications/endpoints/sendmail\ncluster\ncreate_sendmail_endpoint\nCreate a new sendmail endpoint\nname string The name of the endpoint.\nauthor string Author of the mail\ncomment string Comment\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users" + }, + { + "id": "DELETE /cluster/notifications/endpoints/sendmail/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "section": "cluster", + "summary": "delete_sendmail_endpoint", + "description": "Remove sendmail endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\ndelete_sendmail_endpoint\nRemove sendmail endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/sendmail/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "section": "cluster", + "summary": "get_sendmail_endpoint", + "description": "Return a specific sendmail endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\nget_sendmail_endpoint\nReturn a specific sendmail endpoint\nname string" + }, + { + "id": "PUT /cluster/notifications/endpoints/sendmail/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "section": "cluster", + "summary": "update_sendmail_endpoint", + "description": "Update existing sendmail endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "author", + "type": "string", + "required": false, + "description": "Author of the mail" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "delete", + "type": "array", + "required": false, + "description": "A list of settings you want to delete." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + }, + { + "name": "from-address", + "type": "string", + "required": false, + "description": "`From` address for the mail" + }, + { + "name": "mailto", + "type": "array", + "required": false, + "description": "List of email recipients" + }, + { + "name": "mailto-user", + "type": "array", + "required": false, + "description": "List of users" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\nupdate_sendmail_endpoint\nUpdate existing sendmail endpoint\nname string The name of the endpoint.\nauthor string Author of the mail\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users" + }, + { + "id": "GET /cluster/notifications/endpoints/smtp", + "method": "GET", + "path": "/cluster/notifications/endpoints/smtp", + "section": "cluster", + "summary": "get_smtp_endpoints", + "description": "Returns a list of all smtp endpoints", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/smtp\ncluster\nget_smtp_endpoints\nReturns a list of all smtp endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/smtp", + "method": "POST", + "path": "/cluster/notifications/endpoints/smtp", + "section": "cluster", + "summary": "create_smtp_endpoint", + "description": "Create a new smtp endpoint", + "pathParameters": [], + "requestParameters": [ + { + "name": "from-address", + "type": "string", + "required": true, + "description": "`From` address for the mail" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + }, + { + "name": "server", + "type": "string", + "required": true, + "description": "The address of the SMTP server." + }, + { + "name": "author", + "type": "string", + "required": false, + "description": "Author of the mail. Defaults to 'Proxmox VE'." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + }, + { + "name": "mailto", + "type": "array", + "required": false, + "description": "List of email recipients" + }, + { + "name": "mailto-user", + "type": "array", + "required": false, + "description": "List of users" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Determine which encryption method shall be used for the connection.", + "enum": [ + "insecure", + "starttls", + "tls" + ], + "default": "tls" + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "Password for SMTP authentication" + }, + { + "name": "port", + "type": "integer", + "required": false, + "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." + }, + { + "name": "username", + "type": "string", + "required": false, + "description": "Username for SMTP authentication" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/notifications/endpoints/smtp\ncluster\ncreate_smtp_endpoint\nCreate a new smtp endpoint\nfrom-address string `From` address for the mail\nname string The name of the endpoint.\nserver string The address of the SMTP server.\nauthor string Author of the mail. Defaults to 'Proxmox VE'.\ncomment string Comment\ndisable boolean Disable this target\nmailto array List of email recipients\nmailto-user array List of users\nmode string Determine which encryption method shall be used for the connection. insecure starttls tls\npassword string Password for SMTP authentication\nport integer 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.\nusername string Username for SMTP authentication" + }, + { + "id": "DELETE /cluster/notifications/endpoints/smtp/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/smtp/{name}", + "section": "cluster", + "summary": "delete_smtp_endpoint", + "description": "Remove smtp endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/notifications/endpoints/smtp/{name}\ncluster\ndelete_smtp_endpoint\nRemove smtp endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/smtp/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/smtp/{name}", + "section": "cluster", + "summary": "get_smtp_endpoint", + "description": "Return a specific smtp endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/smtp/{name}\ncluster\nget_smtp_endpoint\nReturn a specific smtp endpoint\nname string" + }, + { + "id": "PUT /cluster/notifications/endpoints/smtp/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/smtp/{name}", + "section": "cluster", + "summary": "update_smtp_endpoint", + "description": "Update existing smtp endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "author", + "type": "string", + "required": false, + "description": "Author of the mail. Defaults to 'Proxmox VE'." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "delete", + "type": "array", + "required": false, + "description": "A list of settings you want to delete." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + }, + { + "name": "from-address", + "type": "string", + "required": false, + "description": "`From` address for the mail" + }, + { + "name": "mailto", + "type": "array", + "required": false, + "description": "List of email recipients" + }, + { + "name": "mailto-user", + "type": "array", + "required": false, + "description": "List of users" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Determine which encryption method shall be used for the connection.", + "enum": [ + "insecure", + "starttls", + "tls" + ], + "default": "tls" + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "Password for SMTP authentication" + }, + { + "name": "port", + "type": "integer", + "required": false, + "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." + }, + { + "name": "server", + "type": "string", + "required": false, + "description": "The address of the SMTP server." + }, + { + "name": "username", + "type": "string", + "required": false, + "description": "Username for SMTP authentication" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/notifications/endpoints/smtp/{name}\ncluster\nupdate_smtp_endpoint\nUpdate existing smtp endpoint\nname string The name of the endpoint.\nauthor string Author of the mail. Defaults to 'Proxmox VE'.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users\nmode string Determine which encryption method shall be used for the connection. insecure starttls tls\npassword string Password for SMTP authentication\nport integer 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.\nserver string The address of the SMTP server.\nusername string Username for SMTP authentication" + }, + { + "id": "GET /cluster/notifications/endpoints/webhook", + "method": "GET", + "path": "/cluster/notifications/endpoints/webhook", + "section": "cluster", + "summary": "get_webhook_endpoints", + "description": "Returns a list of all webhook endpoints", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/webhook\ncluster\nget_webhook_endpoints\nReturns a list of all webhook endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/webhook", + "method": "POST", + "path": "/cluster/notifications/endpoints/webhook", + "section": "cluster", + "summary": "create_webhook_endpoint", + "description": "Create a new webhook endpoint", + "pathParameters": [], + "requestParameters": [ + { + "name": "method", + "type": "string", + "required": true, + "description": "HTTP method", + "enum": [ + "post", + "put", + "get" + ] + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + }, + { + "name": "url", + "type": "string", + "required": true, + "description": "Server URL" + }, + { + "name": "body", + "type": "string", + "required": false, + "description": "HTTP body, base64 encoded" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + }, + { + "name": "header", + "type": "array", + "required": false, + "description": "HTTP headers to set. These have to be formatted as a property string in the format name=,value=" + }, + { + "name": "secret", + "type": "array", + "required": false, + "description": "Secrets to set. These have to be formatted as a property string in the format name=,value=" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/notifications/endpoints/webhook\ncluster\ncreate_webhook_endpoint\nCreate a new webhook endpoint\nmethod string HTTP method post put get\nname string The name of the endpoint.\nurl string Server URL\nbody string HTTP body, base64 encoded\ncomment string Comment\ndisable boolean Disable this target\nheader array HTTP headers to set. These have to be formatted as a property string in the format name=,value=\nsecret array Secrets to set. These have to be formatted as a property string in the format name=,value=" + }, + { + "id": "DELETE /cluster/notifications/endpoints/webhook/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/webhook/{name}", + "section": "cluster", + "summary": "delete_webhook_endpoint", + "description": "Remove webhook endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/notifications/endpoints/webhook/{name}\ncluster\ndelete_webhook_endpoint\nRemove webhook endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/webhook/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/webhook/{name}", + "section": "cluster", + "summary": "get_webhook_endpoint", + "description": "Return a specific webhook endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Name of the endpoint.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/endpoints/webhook/{name}\ncluster\nget_webhook_endpoint\nReturn a specific webhook endpoint\nname string Name of the endpoint." + }, + { + "id": "PUT /cluster/notifications/endpoints/webhook/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/webhook/{name}", + "section": "cluster", + "summary": "update_webhook_endpoint", + "description": "Update existing webhook endpoint", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the endpoint.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "body", + "type": "string", + "required": false, + "description": "HTTP body, base64 encoded" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "delete", + "type": "array", + "required": false, + "description": "A list of settings you want to delete." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this target", + "default": 0 + }, + { + "name": "header", + "type": "array", + "required": false, + "description": "HTTP headers to set. These have to be formatted as a property string in the format name=,value=" + }, + { + "name": "method", + "type": "string", + "required": false, + "description": "HTTP method", + "enum": [ + "post", + "put", + "get" + ] + }, + { + "name": "secret", + "type": "array", + "required": false, + "description": "Secrets to set. These have to be formatted as a property string in the format name=,value=" + }, + { + "name": "url", + "type": "string", + "required": false, + "description": "Server URL" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/notifications/endpoints/webhook/{name}\ncluster\nupdate_webhook_endpoint\nUpdate existing webhook endpoint\nname string The name of the endpoint.\nbody string HTTP body, base64 encoded\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nheader array HTTP headers to set. These have to be formatted as a property string in the format name=,value=\nmethod string HTTP method post put get\nsecret array Secrets to set. These have to be formatted as a property string in the format name=,value=\nurl string Server URL" + }, + { + "id": "GET /cluster/notifications/matcher-field-values", + "method": "GET", + "path": "/cluster/notifications/matcher-field-values", + "section": "cluster", + "summary": "get_matcher_field_values", + "description": "Returns known notification metadata fields and their known values", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/matcher-field-values\ncluster\nget_matcher_field_values\nReturns known notification metadata fields and their known values" + }, + { + "id": "GET /cluster/notifications/matcher-fields", + "method": "GET", + "path": "/cluster/notifications/matcher-fields", + "section": "cluster", + "summary": "get_matcher_fields", + "description": "Returns known notification metadata fields", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "name": { + "description": "Name of the field.", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/matcher-fields\ncluster\nget_matcher_fields\nReturns known notification metadata fields" + }, + { + "id": "GET /cluster/notifications/matchers", + "method": "GET", + "path": "/cluster/notifications/matchers", + "section": "cluster", + "summary": "get_matchers", + "description": "Returns a list of all matchers", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/matchers\ncluster\nget_matchers\nReturns a list of all matchers" + }, + { + "id": "POST /cluster/notifications/matchers", + "method": "POST", + "path": "/cluster/notifications/matchers", + "section": "cluster", + "summary": "create_matcher", + "description": "Create a new matcher", + "pathParameters": [], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Name of the matcher.", + "format": "pve-configid" + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this matcher", + "default": 0 + }, + { + "name": "invert-match", + "type": "boolean", + "required": false, + "description": "Invert match of the whole matcher" + }, + { + "name": "match-calendar", + "type": "array", + "required": false, + "description": "Match notification timestamp" + }, + { + "name": "match-field", + "type": "array", + "required": false, + "description": "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=" + }, + { + "name": "match-severity", + "type": "array", + "required": false, + "description": "Notification severities to match" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Choose between 'all' and 'any' for when multiple properties are specified", + "enum": [ + "all", + "any" + ], + "default": "all" + }, + { + "name": "target", + "type": "array", + "required": false, + "description": "Targets to notify on match" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/notifications/matchers\ncluster\ncreate_matcher\nCreate a new matcher\nname string Name of the matcher.\ncomment string Comment\ndisable boolean Disable this matcher\ninvert-match boolean Invert match of the whole matcher\nmatch-calendar array Match notification timestamp\nmatch-field array Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=\nmatch-severity array Notification severities to match\nmode string Choose between 'all' and 'any' for when multiple properties are specified all any\ntarget array Targets to notify on match" + }, + { + "id": "DELETE /cluster/notifications/matchers/{name}", + "method": "DELETE", + "path": "/cluster/notifications/matchers/{name}", + "section": "cluster", + "summary": "delete_matcher", + "description": "Remove matcher", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/notifications/matchers/{name}\ncluster\ndelete_matcher\nRemove matcher\nname string" + }, + { + "id": "GET /cluster/notifications/matchers/{name}", + "method": "GET", + "path": "/cluster/notifications/matchers/{name}", + "section": "cluster", + "summary": "get_matcher", + "description": "Return a specific matcher", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "format": "pve-configid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/matchers/{name}\ncluster\nget_matcher\nReturn a specific matcher\nname string" + }, + { + "id": "PUT /cluster/notifications/matchers/{name}", + "method": "PUT", + "path": "/cluster/notifications/matchers/{name}", + "section": "cluster", + "summary": "update_matcher", + "description": "Update existing matcher", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Name of the matcher.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false, + "description": "Comment" + }, + { + "name": "delete", + "type": "array", + "required": false, + "description": "A list of settings you want to delete." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Disable this matcher", + "default": 0 + }, + { + "name": "invert-match", + "type": "boolean", + "required": false, + "description": "Invert match of the whole matcher" + }, + { + "name": "match-calendar", + "type": "array", + "required": false, + "description": "Match notification timestamp" + }, + { + "name": "match-field", + "type": "array", + "required": false, + "description": "Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=" + }, + { + "name": "match-severity", + "type": "array", + "required": false, + "description": "Notification severities to match" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Choose between 'all' and 'any' for when multiple properties are specified", + "enum": [ + "all", + "any" + ], + "default": "all" + }, + { + "name": "target", + "type": "array", + "required": false, + "description": "Targets to notify on match" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/notifications/matchers/{name}\ncluster\nupdate_matcher\nUpdate existing matcher\nname string Name of the matcher.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this matcher\ninvert-match boolean Invert match of the whole matcher\nmatch-calendar array Match notification timestamp\nmatch-field array Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=\nmatch-severity array Notification severities to match\nmode string Choose between 'all' and 'any' for when multiple properties are specified all any\ntarget array Targets to notify on match" + }, + { + "id": "GET /cluster/notifications/targets", + "method": "GET", + "path": "/cluster/notifications/targets", + "section": "cluster", + "summary": "get_all_targets", + "description": "Returns a list of all entities that can be used as notification targets.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/notifications/targets\ncluster\nget_all_targets\nReturns a list of all entities that can be used as notification targets." + }, + { + "id": "POST /cluster/notifications/targets/{name}/test", + "method": "POST", + "path": "/cluster/notifications/targets/{name}/test", + "section": "cluster", + "summary": "test_target", + "description": "Send a test notification to a provided target.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Name of the target.", + "format": "pve-configid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/notifications/targets/{name}/test\ncluster\ntest_target\nSend a test notification to a provided target.\nname string Name of the target." + }, + { + "id": "GET /cluster/options", + "method": "GET", + "path": "/cluster/options", + "section": "cluster", + "summary": "get_options", + "description": "Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/options\ncluster\nget_options\nGet datacenter options. Without 'Sys.Audit' on '/' not all options are returned." + }, + { + "id": "PUT /cluster/options", + "method": "PUT", + "path": "/cluster/options", + "section": "cluster", + "summary": "set_options", + "description": "Set datacenter options.", + "pathParameters": [], + "requestParameters": [ + { + "name": "bwlimit", + "type": "string", + "required": false, + "description": "Set I/O bandwidth limit for various operations (in KiB/s)." + }, + { + "name": "consent-text", + "type": "string", + "required": false, + "description": "Consent text that is displayed before logging in." + }, + { + "name": "console", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "crs", + "type": "string", + "required": false, + "description": "Cluster resource scheduling settings." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file." + }, + { + "name": "email_from", + "type": "string", + "required": false, + "description": "Specify email address to send notification from (default is root@$hostname)", + "format": "email-opt" + }, + { + "name": "fencing", + "type": "string", + "required": false, + "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" + ], + "default": "watchdog" + }, + { + "name": "ha", + "type": "string", + "required": false, + "description": "Cluster wide HA settings." + }, + { + "name": "http_proxy", + "type": "string", + "required": false, + "description": "Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')" + }, + { + "name": "keyboard", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "language", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "location", + "type": "string", + "required": false, + "description": "The location of the cluster." + }, + { + "name": "mac_prefix", + "type": "string", + "required": false, + "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).", + "default": "BC:24:11", + "format": "mac-prefix" + }, + { + "name": "max_workers", + "type": "integer", + "required": false, + "description": "Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.", + "minimum": 1 + }, + { + "name": "migration", + "type": "string", + "required": false, + "description": "For cluster wide migration settings." + }, + { + "name": "migration_unsecure", + "type": "boolean", + "required": false, + "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!" + }, + { + "name": "next-id", + "type": "string", + "required": false, + "description": "Control the range for the free VMID auto-selection pool." + }, + { + "name": "notify", + "type": "string", + "required": false, + "description": "Cluster-wide notification settings." + }, + { + "name": "registered-tags", + "type": "string", + "required": false, + "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`." + }, + { + "name": "replication", + "type": "string", + "required": false, + "description": "For cluster wide replication settings." + }, + { + "name": "tag-style", + "type": "string", + "required": false, + "description": "Tag style options." + }, + { + "name": "u2f", + "type": "string", + "required": false, + "description": "u2f" + }, + { + "name": "user-tag-access", + "type": "string", + "required": false, + "description": "Privilege options for user-settable tags" + }, + { + "name": "webauthn", + "type": "string", + "required": false, + "description": "webauthn configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/options\ncluster\nset_options\nSet datacenter options.\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\nconsent-text string Consent text that is displayed before logging in.\nconsole string 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. applet vv html5 xtermjs\ncrs string Cluster resource scheduling settings.\ndelete string A list of settings you want to delete.\ndescription string Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.\nemail_from string Specify email address to send notification from (default is root@$hostname)\nfencing string 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 watchdog hardware both\nha string Cluster wide HA settings.\nhttp_proxy string Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')\nkeyboard string Default keybord layout for vnc server. 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\nlanguage string Default GUI language. 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\nlocation string The location of the cluster.\nmac_prefix string 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).\nmax_workers integer Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.\nmigration string For cluster wide migration settings.\nmigration_unsecure boolean 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!\nnext-id string Control the range for the free VMID auto-selection pool.\nnotify string Cluster-wide notification settings.\nregistered-tags string 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`.\nreplication string For cluster wide replication settings.\ntag-style string Tag style options.\nu2f string u2f\nuser-tag-access string Privilege options for user-settable tags\nwebauthn string webauthn configuration" + }, + { + "id": "GET /cluster/qemu", + "method": "GET", + "path": "/cluster/qemu", + "section": "cluster", + "summary": "index", + "description": "Cluster-wide QEMU index", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/qemu\ncluster\nindex\nCluster-wide QEMU index\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/qemu/cpu-flags", + "method": "GET", + "path": "/cluster/qemu/cpu-flags", + "section": "cluster", + "summary": "index", + "description": "List of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64.", + "pathParameters": [], + "requestParameters": [ + { + "name": "accel", + "type": "string", + "required": false, + "description": "Acceleration type to check node compatibility for.", + "enum": [ + "kvm", + "tcg" + ], + "default": "kvm" + }, + { + "name": "arch", + "type": "string", + "required": false, + "description": "Virtual processor architecture. Defaults to the host architecture.", + "enum": [ + "x86_64", + "aarch64" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/nodes", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/mapping/cpu", + [ + "Mapping.Audit", + "Mapping.Use", + "Mapping.Modify" + ], + "any", + 1 + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/qemu/cpu-flags\ncluster\nindex\nList of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64.\naccel string Acceleration type to check node compatibility for. kvm tcg\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/qemu/custom-cpu-models", + "method": "GET", + "path": "/cluster/qemu/custom-cpu-models", + "section": "cluster", + "summary": "config", + "description": "List all custom CPU model definitions visible to the user.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Only lists entries where the user has 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/cpu/'.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/qemu/custom-cpu-models\ncluster\nconfig\nList all custom CPU model definitions visible to the user.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "POST /cluster/qemu/custom-cpu-models", + "method": "POST", + "path": "/cluster/qemu/custom-cpu-models", + "section": "cluster", + "summary": "create", + "description": "Add a custom CPU model definition.", + "pathParameters": [], + "requestParameters": [ + { + "name": "cputype", + "type": "string", + "required": true, + "description": "Name for the custom CPU model. The 'custom-' prefix is optional.", + "format": "pve-configid" + }, + { + "name": "reported-model", + "type": "string", + "required": true, + "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" + ], + "default": "kvm64" + }, + { + "name": "flags", + "type": "string", + "required": false, + "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" + }, + { + "name": "guest-phys-bits", + "type": "integer", + "required": false, + "description": "Number of physical address bits available to the guest.", + "minimum": 32, + "maximum": 64 + }, + { + "name": "hidden", + "type": "boolean", + "required": false, + "description": "Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.", + "default": 0 + }, + { + "name": "hv-vendor-id", + "type": "string", + "required": false, + "description": "The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID." + }, + { + "name": "level", + "type": "integer", + "required": false, + "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.", + "minimum": 0, + "maximum": 4294967295 + }, + { + "name": "phys-bits", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/cpu", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/qemu/custom-cpu-models\ncluster\ncreate\nAdd a custom CPU model definition.\ncputype string Name for the custom CPU model. The 'custom-' prefix is optional.\nreported-model string 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. 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\nflags string 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\nguest-phys-bits integer Number of physical address bits available to the guest.\nhidden boolean Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.\nhv-vendor-id string The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.\nlevel integer 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.\nphys-bits string 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.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "DELETE /cluster/qemu/custom-cpu-models/{cputype}", + "method": "DELETE", + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "section": "cluster", + "summary": "delete", + "description": "Delete a custom CPU model definition.", + "pathParameters": [ + { + "name": "cputype", + "type": "string", + "required": true, + "description": "The custom model to delete. The 'custom-' prefix is optional." + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\ndelete\nDelete a custom CPU model definition.\ncputype string The custom model to delete. The 'custom-' prefix is optional.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/qemu/custom-cpu-models/{cputype}", + "method": "GET", + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "section": "cluster", + "summary": "info", + "description": "Retrieve details about a specific custom CPU model.", + "pathParameters": [ + { + "name": "cputype", + "type": "string", + "required": true, + "description": "Name of the CPU model to query. The 'custom-' prefix is optional." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\ninfo\nRetrieve details about a specific custom CPU model.\ncputype string Name of the CPU model to query. The 'custom-' prefix is optional.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "PUT /cluster/qemu/custom-cpu-models/{cputype}", + "method": "PUT", + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "section": "cluster", + "summary": "update", + "description": "Update a custom CPU model definition.", + "pathParameters": [ + { + "name": "cputype", + "type": "string", + "required": true, + "description": "Name for the custom CPU model. The 'custom-' prefix is optional.", + "format": "pve-configid" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of properties to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "flags", + "type": "string", + "required": false, + "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" + }, + { + "name": "guest-phys-bits", + "type": "integer", + "required": false, + "description": "Number of physical address bits available to the guest.", + "minimum": 32, + "maximum": 64 + }, + { + "name": "hidden", + "type": "boolean", + "required": false, + "description": "Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.", + "default": 0 + }, + { + "name": "hv-vendor-id", + "type": "string", + "required": false, + "description": "The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID." + }, + { + "name": "level", + "type": "integer", + "required": false, + "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.", + "minimum": 0, + "maximum": 4294967295 + }, + { + "name": "phys-bits", + "type": "string", + "required": false, + "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" + }, + { + "name": "reported-model", + "type": "string", + "required": false, + "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" + ], + "default": "kvm64" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\nupdate\nUpdate a custom CPU model definition.\ncputype string Name for the custom CPU model. The 'custom-' prefix is optional.\ndelete string A list of properties to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nflags string 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\nguest-phys-bits integer Number of physical address bits available to the guest.\nhidden boolean Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.\nhv-vendor-id string The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.\nlevel integer 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.\nphys-bits string 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.\nreported-model string 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. 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\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/replication", + "method": "GET", + "path": "/cluster/replication", + "section": "cluster", + "summary": "index", + "description": "List replication jobs.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/replication\ncluster\nindex\nList replication jobs." + }, + { + "id": "POST /cluster/replication", + "method": "POST", + "path": "/cluster/replication", + "section": "cluster", + "summary": "create", + "description": "Create a new replication job", + "pathParameters": [], + "requestParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + }, + { + "name": "target", + "type": "string", + "required": true, + "description": "Target node.", + "format": "pve-node" + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Section type.", + "enum": [ + "local" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable/deactivate the entry." + }, + { + "name": "rate", + "type": "number", + "required": false, + "description": "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum": 1 + }, + { + "name": "remove_job", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "schedule", + "type": "string", + "required": false, + "description": "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "default": "*/15", + "format": "pve-calendar-event" + }, + { + "name": "source", + "type": "string", + "required": false, + "description": "For internal use, to detect if the guest was stolen.", + "format": "pve-node" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/replication\ncluster\ncreate\nCreate a new replication job\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\ntarget string Target node.\ntype string Section type. local\ncomment string Description.\ndisable boolean Flag to disable/deactivate the entry.\nrate number Rate limit in mbps (megabytes per second) as floating point number.\nremove_job string 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. local full\nschedule string Storage replication schedule. The format is a subset of `systemd` calendar events.\nsource string For internal use, to detect if the guest was stolen." + }, + { + "id": "DELETE /cluster/replication/{id}", + "method": "DELETE", + "path": "/cluster/replication/{id}", + "section": "cluster", + "summary": "delete", + "description": "Mark replication job for removal.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Will remove the jobconfig entry, but will not cleanup.", + "default": 0 + }, + { + "name": "keep", + "type": "boolean", + "required": false, + "description": "Keep replicated data at target (do not remove).", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/replication/{id}\ncluster\ndelete\nMark replication job for removal.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nforce boolean Will remove the jobconfig entry, but will not cleanup.\nkeep boolean Keep replicated data at target (do not remove)." + }, + { + "id": "GET /cluster/replication/{id}", + "method": "GET", + "path": "/cluster/replication/{id}", + "section": "cluster", + "summary": "read", + "description": "Read replication job configuration.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/replication/{id}\ncluster\nread\nRead replication job configuration.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'." + }, + { + "id": "PUT /cluster/replication/{id}", + "method": "PUT", + "path": "/cluster/replication/{id}", + "section": "cluster", + "summary": "update", + "description": "Update replication job configuration.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false, + "description": "Description." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable/deactivate the entry." + }, + { + "name": "rate", + "type": "number", + "required": false, + "description": "Rate limit in mbps (megabytes per second) as floating point number.", + "minimum": 1 + }, + { + "name": "remove_job", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "schedule", + "type": "string", + "required": false, + "description": "Storage replication schedule. The format is a subset of `systemd` calendar events.", + "default": "*/15", + "format": "pve-calendar-event" + }, + { + "name": "source", + "type": "string", + "required": false, + "description": "For internal use, to detect if the guest was stolen.", + "format": "pve-node" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/replication/{id}\ncluster\nupdate\nUpdate replication job configuration.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable/deactivate the entry.\nrate number Rate limit in mbps (megabytes per second) as floating point number.\nremove_job string 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. local full\nschedule string Storage replication schedule. The format is a subset of `systemd` calendar events.\nsource string For internal use, to detect if the guest was stolen." + }, + { + "id": "GET /cluster/resources", + "method": "GET", + "path": "/cluster/resources", + "section": "cluster", + "summary": "resources", + "description": "Resources index (cluster wide).", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Resource type.", + "enum": [ + "vm", + "storage", + "node", + "sdn" + ] + } + ], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/resources\ncluster\nresources\nResources index (cluster wide).\ntype string Resource type. vm storage node sdn" + }, + { + "id": "GET /cluster/sdn", + "method": "GET", + "path": "/cluster/sdn", + "section": "cluster", + "summary": "index", + "description": "Directory index.", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/sdn", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn\ncluster\nindex\nDirectory index." + }, + { + "id": "PUT /cluster/sdn", + "method": "PUT", + "path": "/cluster/sdn", + "section": "cluster", + "summary": "reload", + "description": "Apply sdn controller changes && reload.", + "pathParameters": [], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "release-lock", + "type": "boolean", + "required": false, + "description": "When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards", + "default": 1 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn\ncluster\nreload\nApply sdn controller changes && reload.\nlock-token string the token for unlocking the global SDN configuration\nrelease-lock boolean When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards" + }, + { + "id": "GET /cluster/sdn/controllers", + "method": "GET", + "path": "/cluster/sdn/controllers", + "section": "cluster", + "summary": "index", + "description": "SDN controllers index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list sdn controllers of specific type", + "enum": [ + "bgp", + "evpn", + "faucet", + "isis" + ] + } + ], + "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" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/controllers\ncluster\nindex\nSDN controllers index.\npending boolean Display pending config.\nrunning boolean Display running config.\ntype string Only list sdn controllers of specific type bgp evpn faucet isis" + }, + { + "id": "POST /cluster/sdn/controllers", + "method": "POST", + "path": "/cluster/sdn/controllers", + "section": "cluster", + "summary": "create", + "description": "Create a new sdn controller object.", + "pathParameters": [], + "requestParameters": [ + { + "name": "controller", + "type": "string", + "required": true, + "description": "The SDN controller object identifier." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Plugin type.", + "enum": [ + "bgp", + "evpn", + "faucet", + "isis" + ], + "format": "pve-configid" + }, + { + "name": "asn", + "type": "integer", + "required": false, + "description": "autonomous system number", + "minimum": 0, + "maximum": 4294967295 + }, + { + "name": "bgp-mode", + "type": "string", + "required": false, + "description": "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum": [ + "auto", + "external", + "internal" + ], + "default": "auto" + }, + { + "name": "bgp-multipath-as-path-relax", + "type": "boolean", + "required": false, + "description": "Consider different AS paths of equal length for multipath computation." + }, + { + "name": "ebgp", + "type": "boolean", + "required": false, + "description": "Enable eBGP (remote-as external)." + }, + { + "name": "ebgp-multihop", + "type": "integer", + "required": false, + "description": "Set maximum amount of hops for eBGP peers." + }, + { + "name": "fabric", + "type": "string", + "required": false, + "description": "SDN fabric to use as underlay for this EVPN controller.", + "format": "pve-sdn-fabric-id" + }, + { + "name": "isis-domain", + "type": "string", + "required": false, + "description": "Name of the IS-IS domain." + }, + { + "name": "isis-ifaces", + "type": "string", + "required": false, + "description": "Comma-separated list of interfaces where IS-IS should be active.", + "format": "pve-iface-list" + }, + { + "name": "isis-net", + "type": "string", + "required": false, + "description": "Network Entity title for this node in the IS-IS network.", + "format": "pve-sdn-isis-net" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "loopback", + "type": "string", + "required": false, + "description": "Name of the loopback/dummy interface that provides the Router-IP." + }, + { + "name": "node", + "type": "string", + "required": false, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "peer-group-name", + "type": "string", + "required": false, + "description": "Name of the peer group for this EVPN controller", + "default": "VTEP", + "format": "pve-configid" + }, + { + "name": "peers", + "type": "string", + "required": false, + "description": "peers address list.", + "format": "ip-list" + }, + { + "name": "route-map-in", + "type": "string", + "required": false, + "description": "Route Map that should be applied for incoming routes", + "format": "pve-sdn-route-map-id" + }, + { + "name": "route-map-out", + "type": "string", + "required": false, + "description": "Route Map that should be applied for outgoing routes", + "format": "pve-sdn-route-map-id" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/controllers\ncluster\ncreate\nCreate a new sdn controller object.\ncontroller string The SDN controller object identifier.\ntype string Plugin type. bgp evpn faucet isis\nasn integer autonomous system number\nbgp-mode string Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. auto external internal\nbgp-multipath-as-path-relax boolean Consider different AS paths of equal length for multipath computation.\nebgp boolean Enable eBGP (remote-as external).\nebgp-multihop integer Set maximum amount of hops for eBGP peers.\nfabric string SDN fabric to use as underlay for this EVPN controller.\nisis-domain string Name of the IS-IS domain.\nisis-ifaces string Comma-separated list of interfaces where IS-IS should be active.\nisis-net string Network Entity title for this node in the IS-IS network.\nlock-token string the token for unlocking the global SDN configuration\nloopback string Name of the loopback/dummy interface that provides the Router-IP.\nnode string The cluster node name.\nnodes string List of cluster node names.\npeer-group-name string Name of the peer group for this EVPN controller\npeers string peers address list.\nroute-map-in string Route Map that should be applied for incoming routes\nroute-map-out string Route Map that should be applied for outgoing routes" + }, + { + "id": "DELETE /cluster/sdn/controllers/{controller}", + "method": "DELETE", + "path": "/cluster/sdn/controllers/{controller}", + "section": "cluster", + "summary": "delete", + "description": "Delete sdn controller object configuration.", + "pathParameters": [ + { + "name": "controller", + "type": "string", + "required": true, + "description": "The SDN controller object identifier." + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/controllers/{controller}\ncluster\ndelete\nDelete sdn controller object configuration.\ncontroller string The SDN controller object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/controllers/{controller}", + "method": "GET", + "path": "/cluster/sdn/controllers/{controller}", + "section": "cluster", + "summary": "read", + "description": "Read sdn controller configuration.", + "pathParameters": [ + { + "name": "controller", + "type": "string", + "required": true, + "description": "The SDN controller object identifier." + } + ], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/sdn/controllers/{controller}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "GET\n/cluster/sdn/controllers/{controller}\ncluster\nread\nRead sdn controller configuration.\ncontroller string The SDN controller object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/controllers/{controller}", + "method": "PUT", + "path": "/cluster/sdn/controllers/{controller}", + "section": "cluster", + "summary": "update", + "description": "Update sdn controller object configuration.", + "pathParameters": [ + { + "name": "controller", + "type": "string", + "required": true, + "description": "The SDN controller object identifier." + } + ], + "requestParameters": [ + { + "name": "asn", + "type": "integer", + "required": false, + "description": "autonomous system number", + "minimum": 0, + "maximum": 4294967295 + }, + { + "name": "bgp-mode", + "type": "string", + "required": false, + "description": "Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.", + "enum": [ + "auto", + "external", + "internal" + ], + "default": "auto" + }, + { + "name": "bgp-multipath-as-path-relax", + "type": "boolean", + "required": false, + "description": "Consider different AS paths of equal length for multipath computation." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "ebgp", + "type": "boolean", + "required": false, + "description": "Enable eBGP (remote-as external)." + }, + { + "name": "ebgp-multihop", + "type": "integer", + "required": false, + "description": "Set maximum amount of hops for eBGP peers." + }, + { + "name": "fabric", + "type": "string", + "required": false, + "description": "SDN fabric to use as underlay for this EVPN controller.", + "format": "pve-sdn-fabric-id" + }, + { + "name": "isis-domain", + "type": "string", + "required": false, + "description": "Name of the IS-IS domain." + }, + { + "name": "isis-ifaces", + "type": "string", + "required": false, + "description": "Comma-separated list of interfaces where IS-IS should be active.", + "format": "pve-iface-list" + }, + { + "name": "isis-net", + "type": "string", + "required": false, + "description": "Network Entity title for this node in the IS-IS network.", + "format": "pve-sdn-isis-net" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "loopback", + "type": "string", + "required": false, + "description": "Name of the loopback/dummy interface that provides the Router-IP." + }, + { + "name": "node", + "type": "string", + "required": false, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "peer-group-name", + "type": "string", + "required": false, + "description": "Name of the peer group for this EVPN controller", + "default": "VTEP", + "format": "pve-configid" + }, + { + "name": "peers", + "type": "string", + "required": false, + "description": "peers address list.", + "format": "ip-list" + }, + { + "name": "route-map-in", + "type": "string", + "required": false, + "description": "Route Map that should be applied for incoming routes", + "format": "pve-sdn-route-map-id" + }, + { + "name": "route-map-out", + "type": "string", + "required": false, + "description": "Route Map that should be applied for outgoing routes", + "format": "pve-sdn-route-map-id" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/controllers/{controller}\ncluster\nupdate\nUpdate sdn controller object configuration.\ncontroller string The SDN controller object identifier.\nasn integer autonomous system number\nbgp-mode string Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. auto external internal\nbgp-multipath-as-path-relax boolean Consider different AS paths of equal length for multipath computation.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nebgp boolean Enable eBGP (remote-as external).\nebgp-multihop integer Set maximum amount of hops for eBGP peers.\nfabric string SDN fabric to use as underlay for this EVPN controller.\nisis-domain string Name of the IS-IS domain.\nisis-ifaces string Comma-separated list of interfaces where IS-IS should be active.\nisis-net string Network Entity title for this node in the IS-IS network.\nlock-token string the token for unlocking the global SDN configuration\nloopback string Name of the loopback/dummy interface that provides the Router-IP.\nnode string The cluster node name.\nnodes string List of cluster node names.\npeer-group-name string Name of the peer group for this EVPN controller\npeers string peers address list.\nroute-map-in string Route Map that should be applied for incoming routes\nroute-map-out string Route Map that should be applied for outgoing routes" + }, + { + "id": "GET /cluster/sdn/dns", + "method": "GET", + "path": "/cluster/sdn/dns", + "section": "cluster", + "summary": "index", + "description": "SDN dns index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list sdn dns of specific type", + "enum": [ + "powerdns" + ] + } + ], + "returns": { + "items": { + "properties": { + "dns": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{dns}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/dns\ncluster\nindex\nSDN dns index.\ntype string Only list sdn dns of specific type powerdns" + }, + { + "id": "POST /cluster/sdn/dns", + "method": "POST", + "path": "/cluster/sdn/dns", + "section": "cluster", + "summary": "create", + "description": "Create a new sdn dns object.", + "pathParameters": [], + "requestParameters": [ + { + "name": "dns", + "type": "string", + "required": true, + "description": "The SDN dns object identifier." + }, + { + "name": "key", + "type": "string", + "required": true + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Plugin type.", + "enum": [ + "powerdns" + ], + "format": "pve-configid" + }, + { + "name": "url", + "type": "string", + "required": true + }, + { + "name": "fingerprint", + "type": "string", + "required": false, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "reversemaskv6", + "type": "integer", + "required": false + }, + { + "name": "reversev6mask", + "type": "integer", + "required": false + }, + { + "name": "ttl", + "type": "integer", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/dns\ncluster\ncreate\nCreate a new sdn dns object.\ndns string The SDN dns object identifier.\nkey string\ntype string Plugin type. powerdns\nurl string\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nreversemaskv6 integer\nreversev6mask integer\nttl integer" + }, + { + "id": "DELETE /cluster/sdn/dns/{dns}", + "method": "DELETE", + "path": "/cluster/sdn/dns/{dns}", + "section": "cluster", + "summary": "delete", + "description": "Delete sdn dns object configuration.", + "pathParameters": [ + { + "name": "dns", + "type": "string", + "required": true, + "description": "The SDN dns object identifier." + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/dns/{dns}\ncluster\ndelete\nDelete sdn dns object configuration.\ndns string The SDN dns object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/dns/{dns}", + "method": "GET", + "path": "/cluster/sdn/dns/{dns}", + "section": "cluster", + "summary": "read", + "description": "Read sdn dns configuration.", + "pathParameters": [ + { + "name": "dns", + "type": "string", + "required": true, + "description": "The SDN dns object identifier." + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/sdn/dns/{dns}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/dns/{dns}\ncluster\nread\nRead sdn dns configuration.\ndns string The SDN dns object identifier." + }, + { + "id": "PUT /cluster/sdn/dns/{dns}", + "method": "PUT", + "path": "/cluster/sdn/dns/{dns}", + "section": "cluster", + "summary": "update", + "description": "Update sdn dns object configuration.", + "pathParameters": [ + { + "name": "dns", + "type": "string", + "required": true, + "description": "The SDN dns object identifier." + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "fingerprint", + "type": "string", + "required": false, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "key", + "type": "string", + "required": false + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "reversemaskv6", + "type": "integer", + "required": false + }, + { + "name": "ttl", + "type": "integer", + "required": false + }, + { + "name": "url", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/dns/{dns}\ncluster\nupdate\nUpdate sdn dns object configuration.\ndns string The SDN dns object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfingerprint string Certificate SHA 256 fingerprint.\nkey string\nlock-token string the token for unlocking the global SDN configuration\nreversemaskv6 integer\nttl integer\nurl string" + }, + { + "id": "GET /cluster/sdn/dry-run", + "method": "GET", + "path": "/cluster/sdn/dry-run", + "section": "cluster", + "summary": "dry-run", + "description": "Dry-run the SDN apply action and return the difference between the current configuration and the pending configuration", + "pathParameters": [], + "requestParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/dry-run\ncluster\ndry-run\nDry-run the SDN apply action and return the difference between the current configuration and the pending configuration\nnode string The cluster node name." + }, + { + "id": "GET /cluster/sdn/fabrics", + "method": "GET", + "path": "/cluster/sdn/fabrics", + "section": "cluster", + "summary": "index", + "description": "SDN Fabrics Index", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/fabrics\ncluster\nindex\nSDN Fabrics Index" + }, + { + "id": "GET /cluster/sdn/fabrics/all", + "method": "GET", + "path": "/cluster/sdn/fabrics/all", + "section": "cluster", + "summary": "list_all", + "description": "SDN Fabrics Index", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + } + }, + "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" + }, + "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" + }, + "raw": { + "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" + } + }, + "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" + } + }, + "searchText": "GET\n/cluster/sdn/fabrics/all\ncluster\nlist_all\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "GET /cluster/sdn/fabrics/fabric", + "method": "GET", + "path": "/cluster/sdn/fabrics/fabric", + "section": "cluster", + "summary": "index", + "description": "SDN Fabrics Index", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/fabrics/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/fabrics/fabric\ncluster\nindex\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/fabrics/fabric", + "method": "POST", + "path": "/cluster/sdn/fabrics/fabric", + "section": "cluster", + "summary": "add_fabric", + "description": "Add a fabric", + "pathParameters": [], + "requestParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "protocol", + "type": "string", + "required": true, + "description": "Type of configuration entry in an SDN Fabric section config", + "enum": [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ] + }, + { + "name": "redistribute", + "type": "array", + "required": true + }, + { + "name": "area", + "type": "string", + "required": false, + "description": "OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust." + }, + { + "name": "csnp_interval", + "type": "number", + "required": false, + "description": "The csnp_interval property for Openfabric", + "minimum": 1, + "maximum": 600 + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "hello_interval", + "type": "number", + "required": false, + "description": "The hello_interval property for Openfabric", + "minimum": 1, + "maximum": 600 + }, + { + "name": "ip_prefix", + "type": "string", + "required": false, + "description": "The IP prefix for Node IPs", + "format": "CIDR" + }, + { + "name": "ip6_prefix", + "type": "string", + "required": false, + "description": "The IP prefix for Node IPs", + "format": "CIDR" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "persistent_keepalive", + "type": "number", + "required": false, + "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", + "minimum": 0, + "maximum": 65535 + }, + { + "name": "route_filter", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/fabrics/fabric\ncluster\nadd_fabric\nAdd a fabric\nid string Identifier for SDN fabrics\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nredistribute array\narea string OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.\ncsnp_interval number The csnp_interval property for Openfabric\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nhello_interval number The hello_interval property for Openfabric\nip_prefix string The IP prefix for Node IPs\nip6_prefix string The IP prefix for Node IPs\nlock-token string the token for unlocking the global SDN configuration\npersistent_keepalive number 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\nroute_filter string A prefix list that should be used for filtering routes that are to be installed into the kernel routing table" + }, + { + "id": "DELETE /cluster/sdn/fabrics/fabric/{id}", + "method": "DELETE", + "path": "/cluster/sdn/fabrics/fabric/{id}", + "section": "cluster", + "summary": "delete_fabric", + "description": "Add a fabric", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/fabrics/fabric/{id}\ncluster\ndelete_fabric\nAdd a fabric\nid string Identifier for SDN fabrics" + }, + { + "id": "GET /cluster/sdn/fabrics/fabric/{id}", + "method": "GET", + "path": "/cluster/sdn/fabrics/fabric/{id}", + "section": "cluster", + "summary": "get_fabric", + "description": "Update a fabric", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/fabrics/fabric/{id}\ncluster\nget_fabric\nUpdate a fabric\nid string Identifier for SDN fabrics" + }, + { + "id": "PUT /cluster/sdn/fabrics/fabric/{id}", + "method": "PUT", + "path": "/cluster/sdn/fabrics/fabric/{id}", + "section": "cluster", + "summary": "update_fabric", + "description": "Update a fabric", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "array", + "required": true + }, + { + "name": "protocol", + "type": "string", + "required": true, + "description": "Type of configuration entry in an SDN Fabric section config", + "enum": [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ] + }, + { + "name": "redistribute", + "type": "array", + "required": true + }, + { + "name": "area", + "type": "string", + "required": false, + "description": "OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust." + }, + { + "name": "csnp_interval", + "type": "number", + "required": false, + "description": "The csnp_interval property for Openfabric", + "minimum": 1, + "maximum": 600 + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "hello_interval", + "type": "number", + "required": false, + "description": "The hello_interval property for Openfabric", + "minimum": 1, + "maximum": 600 + }, + { + "name": "ip_prefix", + "type": "string", + "required": false, + "description": "The IP prefix for Node IPs", + "format": "CIDR" + }, + { + "name": "ip6_prefix", + "type": "string", + "required": false, + "description": "The IP prefix for Node IPs", + "format": "CIDR" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "persistent_keepalive", + "type": "number", + "required": false, + "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", + "minimum": 0, + "maximum": 65535 + }, + { + "name": "route_filter", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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": [ + "hello_interval", + "csnp_interval", + "route_filter" + ], + "type": "string" + }, + "optional": 1, + "type": "array" + }, + { + "instance-types": [ + "bgp" + ], + "items": { + "enum": [ + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/fabrics/fabric/{id}\ncluster\nupdate_fabric\nUpdate a fabric\nid string Identifier for SDN fabrics\ndelete array\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nredistribute array\narea string OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.\ncsnp_interval number The csnp_interval property for Openfabric\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nhello_interval number The hello_interval property for Openfabric\nip_prefix string The IP prefix for Node IPs\nip6_prefix string The IP prefix for Node IPs\nlock-token string the token for unlocking the global SDN configuration\npersistent_keepalive number 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\nroute_filter string A prefix list that should be used for filtering routes that are to be installed into the kernel routing table" + }, + { + "id": "GET /cluster/sdn/fabrics/node", + "method": "GET", + "path": "/cluster/sdn/fabrics/node", + "section": "cluster", + "summary": "list_nodes", + "description": "SDN Fabrics Index", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + } + }, + "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" + }, + "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" + }, + "raw": { + "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" + } + }, + "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" + } + }, + "searchText": "GET\n/cluster/sdn/fabrics/node\ncluster\nlist_nodes\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "GET /cluster/sdn/fabrics/node/{fabric_id}", + "method": "GET", + "path": "/cluster/sdn/fabrics/node/{fabric_id}", + "section": "cluster", + "summary": "list_nodes_fabric", + "description": "SDN Fabrics Index", + "pathParameters": [ + { + "name": "fabric_id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + } + ], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + } + }, + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit" + ] + ], + "description": "Only returns nodes where you have 'Sys.Audit' or 'Sys.Modify' permissions." + }, + "raw": { + "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" + } + }, + "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" + } + }, + "searchText": "GET\n/cluster/sdn/fabrics/node/{fabric_id}\ncluster\nlist_nodes_fabric\nSDN Fabrics Index\nfabric_id string Identifier for SDN fabrics\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/fabrics/node/{fabric_id}", + "method": "POST", + "path": "/cluster/sdn/fabrics/node/{fabric_id}", + "section": "cluster", + "summary": "add_node", + "description": "Add a node", + "pathParameters": [ + { + "name": "fabric_id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + } + ], + "requestParameters": [ + { + "name": "interfaces", + "type": "array", + "required": true + }, + { + "name": "node_id", + "type": "string", + "required": true, + "description": "Identifier for nodes in an SDN fabric", + "format": "pve-node" + }, + { + "name": "protocol", + "type": "string", + "required": true, + "description": "Type of configuration entry in an SDN Fabric section config", + "enum": [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ] + }, + { + "name": "allowed_ips", + "type": "array", + "required": false, + "description": "A list of IPs that are routable via this node in the WireGuard fabric." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "endpoint", + "type": "string", + "required": false, + "description": "The endpoint used for connecting to this node." + }, + { + "name": "ip", + "type": "string", + "required": false, + "description": "IPv4 address for this node", + "format": "ipv4" + }, + { + "name": "ip6", + "type": "string", + "required": false, + "description": "IPv6 address for this node", + "format": "ipv6" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "peers", + "type": "array", + "required": false + }, + { + "name": "public_key", + "type": "string", + "required": false, + "description": "The public key for the external node." + }, + { + "name": "role", + "type": "string", + "required": false, + "description": "The role of this node in the WireGuard fabric.", + "enum": [ + "internal", + "external" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "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" + } + }, + "searchText": "POST\n/cluster/sdn/fabrics/node/{fabric_id}\ncluster\nadd_node\nAdd a node\nfabric_id string Identifier for SDN fabrics\ninterfaces array\nnode_id string Identifier for nodes in an SDN fabric\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nallowed_ips array A list of IPs that are routable via this node in the WireGuard fabric.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nendpoint string The endpoint used for connecting to this node.\nip string IPv4 address for this node\nip6 string IPv6 address for this node\nlock-token string the token for unlocking the global SDN configuration\npeers array\npublic_key string The public key for the external node.\nrole string The role of this node in the WireGuard fabric. internal external" + }, + { + "id": "DELETE /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "method": "DELETE", + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "section": "cluster", + "summary": "delete_node", + "description": "Add a node", + "pathParameters": [ + { + "name": "fabric_id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "node_id", + "type": "string", + "required": true, + "description": "Identifier for nodes in an SDN fabric", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\ndelete_node\nAdd a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric" + }, + { + "id": "GET /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "method": "GET", + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "section": "cluster", + "summary": "get_node", + "description": "Get a node", + "pathParameters": [ + { + "name": "fabric_id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "node_id", + "type": "string", + "required": true, + "description": "Identifier for nodes in an SDN fabric", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + } + }, + "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" + } + } + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + ] + }, + "raw": { + "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" + } + }, + "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" + } + } + } + }, + "searchText": "GET\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\nget_node\nGet a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric" + }, + { + "id": "PUT /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "method": "PUT", + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "section": "cluster", + "summary": "update_node", + "description": "Update a node", + "pathParameters": [ + { + "name": "fabric_id", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "node_id", + "type": "string", + "required": true, + "description": "Identifier for nodes in an SDN fabric", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "array", + "required": true + }, + { + "name": "interfaces", + "type": "array", + "required": true + }, + { + "name": "protocol", + "type": "string", + "required": true, + "description": "Type of configuration entry in an SDN Fabric section config", + "enum": [ + "openfabric", + "ospf", + "wireguard", + "bgp" + ] + }, + { + "name": "allowed_ips", + "type": "array", + "required": false, + "description": "A list of IPs that are routable via this node in the WireGuard fabric." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "endpoint", + "type": "string", + "required": false, + "description": "The endpoint used for connecting to this node." + }, + { + "name": "ip", + "type": "string", + "required": false, + "description": "IPv4 address for this node", + "format": "ipv4" + }, + { + "name": "ip6", + "type": "string", + "required": false, + "description": "IPv6 address for this node", + "format": "ipv6" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "peers", + "type": "array", + "required": false + }, + { + "name": "public_key", + "type": "string", + "required": false, + "description": "The public key for the external node." + }, + { + "name": "role", + "type": "string", + "required": false, + "description": "The role of this node in the WireGuard fabric.", + "enum": [ + "internal", + "external" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\nupdate_node\nUpdate a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric\ndelete array\ninterfaces array\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nallowed_ips array A list of IPs that are routable via this node in the WireGuard fabric.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nendpoint string The endpoint used for connecting to this node.\nip string IPv4 address for this node\nip6 string IPv6 address for this node\nlock-token string the token for unlocking the global SDN configuration\npeers array\npublic_key string The public key for the external node.\nrole string The role of this node in the WireGuard fabric. internal external" + }, + { + "id": "GET /cluster/sdn/ipams", + "method": "GET", + "path": "/cluster/sdn/ipams", + "section": "cluster", + "summary": "index", + "description": "SDN ipams index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list sdn ipams of specific type", + "enum": [ + "netbox", + "phpipam", + "pve" + ] + } + ], + "returns": { + "items": { + "properties": { + "ipam": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{ipam}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/ipams\ncluster\nindex\nSDN ipams index.\ntype string Only list sdn ipams of specific type netbox phpipam pve" + }, + { + "id": "POST /cluster/sdn/ipams", + "method": "POST", + "path": "/cluster/sdn/ipams", + "section": "cluster", + "summary": "create", + "description": "Create a new sdn ipam object.", + "pathParameters": [], + "requestParameters": [ + { + "name": "ipam", + "type": "string", + "required": true, + "description": "The SDN ipam object identifier." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Plugin type.", + "enum": [ + "netbox", + "phpipam", + "pve" + ], + "format": "pve-configid" + }, + { + "name": "fingerprint", + "type": "string", + "required": false, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "section", + "type": "integer", + "required": false + }, + { + "name": "token", + "type": "string", + "required": false + }, + { + "name": "url", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/ipams\ncluster\ncreate\nCreate a new sdn ipam object.\nipam string The SDN ipam object identifier.\ntype string Plugin type. netbox phpipam pve\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nsection integer\ntoken string\nurl string" + }, + { + "id": "DELETE /cluster/sdn/ipams/{ipam}", + "method": "DELETE", + "path": "/cluster/sdn/ipams/{ipam}", + "section": "cluster", + "summary": "delete", + "description": "Delete sdn ipam object configuration.", + "pathParameters": [ + { + "name": "ipam", + "type": "string", + "required": true, + "description": "The SDN ipam object identifier." + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/ipams/{ipam}\ncluster\ndelete\nDelete sdn ipam object configuration.\nipam string The SDN ipam object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/ipams/{ipam}", + "method": "GET", + "path": "/cluster/sdn/ipams/{ipam}", + "section": "cluster", + "summary": "read", + "description": "Read sdn ipam configuration.", + "pathParameters": [ + { + "name": "ipam", + "type": "string", + "required": true, + "description": "The SDN ipam object identifier." + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/sdn/ipams/{ipam}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/ipams/{ipam}\ncluster\nread\nRead sdn ipam configuration.\nipam string The SDN ipam object identifier." + }, + { + "id": "PUT /cluster/sdn/ipams/{ipam}", + "method": "PUT", + "path": "/cluster/sdn/ipams/{ipam}", + "section": "cluster", + "summary": "update", + "description": "Update sdn ipam object configuration.", + "pathParameters": [ + { + "name": "ipam", + "type": "string", + "required": true, + "description": "The SDN ipam object identifier." + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "fingerprint", + "type": "string", + "required": false, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "section", + "type": "integer", + "required": false + }, + { + "name": "token", + "type": "string", + "required": false + }, + { + "name": "url", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/ipams/{ipam}\ncluster\nupdate\nUpdate sdn ipam object configuration.\nipam string The SDN ipam object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nsection integer\ntoken string\nurl string" + }, + { + "id": "GET /cluster/sdn/ipams/{ipam}/status", + "method": "GET", + "path": "/cluster/sdn/ipams/{ipam}/status", + "section": "cluster", + "summary": "ipamindex", + "description": "List PVE IPAM Entries", + "pathParameters": [ + { + "name": "ipam", + "type": "string", + "required": true, + "description": "The SDN ipam object identifier." + } + ], + "requestParameters": [], + "returns": { + "type": "array" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/ipams/{ipam}/status\ncluster\nipamindex\nList PVE IPAM Entries\nipam string The SDN ipam object identifier." + }, + { + "id": "DELETE /cluster/sdn/lock", + "method": "DELETE", + "path": "/cluster/sdn/lock", + "section": "cluster", + "summary": "release_lock", + "description": "Release global lock for SDN configuration", + "pathParameters": [], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "if true, allow releasing lock without providing the token", + "default": 0 + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/lock\ncluster\nrelease_lock\nRelease global lock for SDN configuration\nforce boolean if true, allow releasing lock without providing the token\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "POST /cluster/sdn/lock", + "method": "POST", + "path": "/cluster/sdn/lock", + "section": "cluster", + "summary": "lock", + "description": "Acquire global lock for SDN configuration", + "pathParameters": [], + "requestParameters": [ + { + "name": "allow-pending", + "type": "boolean", + "required": false, + "description": "if true, allow acquiring lock even though there are pending changes", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/lock\ncluster\nlock\nAcquire global lock for SDN configuration\nallow-pending boolean if true, allow acquiring lock even though there are pending changes" + }, + { + "id": "GET /cluster/sdn/prefix-lists", + "method": "GET", + "path": "/cluster/sdn/prefix-lists", + "section": "cluster", + "summary": "list_prefix_lists", + "description": "List Prefix Lists", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + }, + { + "name": "verbose", + "type": "boolean", + "required": false, + "description": "If 0, only returns id - otherwise returns all properties." + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "description": "Only returns prefix list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/prefix-lists\ncluster\nlist_prefix_lists\nList Prefix Lists\npending boolean Display pending config.\nrunning boolean Display running config.\nverbose boolean If 0, only returns id - otherwise returns all properties." + }, + { + "id": "POST /cluster/sdn/prefix-lists", + "method": "POST", + "path": "/cluster/sdn/prefix-lists", + "section": "cluster", + "summary": "create_prefix_list_entry", + "description": "Create Prefix List", + "pathParameters": [], + "requestParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "entries", + "type": "array", + "required": false + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/prefix-lists\ncluster\ncreate_prefix_list_entry\nCreate Prefix List\nid string The SDN prefix list identifier\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nentries array\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "DELETE /cluster/sdn/prefix-lists/{id}", + "method": "DELETE", + "path": "/cluster/sdn/prefix-lists/{id}", + "section": "cluster", + "summary": "delete_prefix_list", + "description": "Delete Prefix List", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/prefix-lists/{id}\ncluster\ndelete_prefix_list\nDelete Prefix List\nid string The SDN prefix list identifier\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/prefix-lists/{id}", + "method": "GET", + "path": "/cluster/sdn/prefix-lists/{id}", + "section": "cluster", + "summary": "get_prefix_list", + "description": "Get Prefix List", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/prefix-lists/{id}\ncluster\nget_prefix_list\nGet Prefix List\nid string The SDN prefix list identifier" + }, + { + "id": "PUT /cluster/sdn/prefix-lists/{id}", + "method": "PUT", + "path": "/cluster/sdn/prefix-lists/{id}", + "section": "cluster", + "summary": "update_prefix_list", + "description": "Update Prefix List", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "array", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "entries", + "type": "array", + "required": false + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/prefix-lists/{id}\ncluster\nupdate_prefix_list\nUpdate Prefix List\nid string The SDN prefix list identifier\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nentries array\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/prefix-lists/{id}/entries", + "method": "GET", + "path": "/cluster/sdn/prefix-lists/{id}/entries", + "section": "cluster", + "summary": "get_prefix_list_entries", + "description": "List Prefix List Entries", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{seq}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/prefix-lists/{id}/entries\ncluster\nget_prefix_list_entries\nList Prefix List Entries\nid string The SDN prefix list identifier" + }, + { + "id": "POST /cluster/sdn/prefix-lists/{id}/entries", + "method": "POST", + "path": "/cluster/sdn/prefix-lists/{id}/entries", + "section": "cluster", + "summary": "create_prefix_list_entry", + "description": "Create Prefix List Entry", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "enum": [ + "permit", + "deny" + ] + }, + { + "name": "prefix", + "type": "string", + "required": true, + "format": "FullRangeCIDR" + }, + { + "name": "ge", + "type": "integer", + "required": false, + "minimum": 0, + "maximum": 128 + }, + { + "name": "le", + "type": "integer", + "required": false, + "minimum": 0, + "maximum": 128 + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "seq", + "type": "integer", + "required": false, + "minimum": 1, + "maximum": 4294967295 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/prefix-lists/{id}/entries\ncluster\ncreate_prefix_list_entry\nCreate Prefix List Entry\nid string The SDN prefix list identifier\naction string permit deny\nprefix string\nge integer\nle integer\nlock-token string the token for unlocking the global SDN configuration\nseq integer" + }, + { + "id": "DELETE /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "method": "DELETE", + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "section": "cluster", + "summary": "delete_prefix_list_entry", + "description": "Delete Prefix List Entry", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\ndelete_prefix_list_entry\nDelete Prefix List Entry\nid string The SDN prefix list identifier\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "method": "GET", + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "section": "cluster", + "summary": "get_prefix_list_entry", + "description": "Get Prefix List Entry", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The SDN prefix list identifier", + "format": "pve-sdn-prefix-list-id" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\nget_prefix_list_entry\nGet Prefix List Entry\nid string The SDN prefix list identifier" + }, + { + "id": "PUT /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "method": "PUT", + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "section": "cluster", + "summary": "update_prefix_list_entry", + "description": "Update Prefix List Entry", + "pathParameters": [], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "enum": [ + "permit", + "deny" + ] + }, + { + "name": "delete", + "type": "array", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "ge", + "type": "integer", + "required": false, + "minimum": 0, + "maximum": 128 + }, + { + "name": "le", + "type": "integer", + "required": false, + "minimum": 0, + "maximum": 128 + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "prefix", + "type": "string", + "required": false, + "format": "FullRangeCIDR" + }, + { + "name": "seq", + "type": "integer", + "required": false, + "minimum": 1, + "maximum": 4294967295 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\nupdate_prefix_list_entry\nUpdate Prefix List Entry\naction string permit deny\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nge integer\nle integer\nlock-token string the token for unlocking the global SDN configuration\nprefix string\nseq integer" + }, + { + "id": "POST /cluster/sdn/rollback", + "method": "POST", + "path": "/cluster/sdn/rollback", + "section": "cluster", + "summary": "rollback", + "description": "Rollback pending changes to SDN configuration", + "pathParameters": [], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "release-lock", + "type": "boolean", + "required": false, + "description": "When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards", + "default": 1 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/rollback\ncluster\nrollback\nRollback pending changes to SDN configuration\nlock-token string the token for unlocking the global SDN configuration\nrelease-lock boolean When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards" + }, + { + "id": "GET /cluster/sdn/route-maps", + "method": "GET", + "path": "/cluster/sdn/route-maps", + "section": "cluster", + "summary": "list_route_maps", + "description": "List Route Maps", + "pathParameters": [], + "requestParameters": [ + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + }, + "permissions": { + "description": "Only returns route maps where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/route-maps\ncluster\nlist_route_maps\nList Route Maps\nrunning boolean Display running config." + }, + { + "id": "GET /cluster/sdn/route-maps/entries", + "method": "GET", + "path": "/cluster/sdn/route-maps/entries", + "section": "cluster", + "summary": "list_route_map_entries", + "description": "Lists all route map entries.", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + }, + "permissions": { + "description": "Only returns route map entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/route-maps/entries\ncluster\nlist_route_map_entries\nLists all route map entries.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/route-maps/entries", + "method": "POST", + "path": "/cluster/sdn/route-maps/entries", + "section": "cluster", + "summary": "create_route_map_entry", + "description": "Create Route Map entry", + "pathParameters": [], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Matching policy of a route map entry.", + "enum": [ + "permit", + "deny" + ] + }, + { + "name": "order", + "type": "integer", + "required": true, + "description": "The index of this route map entry", + "minimum": 0, + "maximum": 65535 + }, + { + "name": "route-map-id", + "type": "string", + "required": true, + "description": "The SDN route map identifier", + "format": "pve-sdn-route-map-id" + }, + { + "name": "call", + "type": "string", + "required": false, + "description": "The SDN route map identifier", + "format": "pve-sdn-route-map-id" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "exit-action", + "type": "string", + "required": false + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "match", + "type": "array", + "required": false + }, + { + "name": "set", + "type": "array", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/route-maps", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/route-maps/entries\ncluster\ncreate_route_map_entry\nCreate Route Map entry\naction string Matching policy of a route map entry. permit deny\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\ncall string The SDN route map identifier\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nexit-action string\nlock-token string the token for unlocking the global SDN configuration\nmatch array\nset array" + }, + { + "id": "GET /cluster/sdn/route-maps/entries/{route-map-id}", + "method": "GET", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}", + "section": "cluster", + "summary": "list_route_map_entries_for_route_map", + "description": "List all entries for a given Route Map", + "pathParameters": [ + { + "name": "route-map-id", + "type": "string", + "required": true, + "description": "The SDN route map identifier", + "format": "pve-sdn-route-map-id" + } + ], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/route-maps/entries/{route-map-id}\ncluster\nlist_route_map_entries_for_route_map\nList all entries for a given Route Map\nroute-map-id string The SDN route map identifier\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "DELETE /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "method": "DELETE", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "section": "cluster", + "summary": "delete_route_map_entry", + "description": "Delete Route Map Entry", + "pathParameters": [ + { + "name": "order", + "type": "integer", + "required": true, + "description": "The index of this route map entry", + "minimum": 0, + "maximum": 65535 + }, + { + "name": "route-map-id", + "type": "string", + "required": true, + "description": "The SDN route map identifier", + "format": "pve-sdn-route-map-id" + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\ndelete_route_map_entry\nDelete Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "method": "GET", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "section": "cluster", + "summary": "get_route_map_entry", + "description": "Get Route Map Entry", + "pathParameters": [ + { + "name": "order", + "type": "integer", + "required": true, + "description": "The index of this route map entry", + "minimum": 0, + "maximum": 65535 + }, + { + "name": "route-map-id", + "type": "string", + "required": true, + "description": "The SDN route map identifier", + "format": "pve-sdn-route-map-id" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\nget_route_map_entry\nGet Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier" + }, + { + "id": "PUT /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "method": "PUT", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "section": "cluster", + "summary": "update_route_map_entry", + "description": "Update Route Map Entry", + "pathParameters": [ + { + "name": "order", + "type": "integer", + "required": true, + "description": "The index of this route map entry", + "minimum": 0, + "maximum": 65535 + }, + { + "name": "route-map-id", + "type": "string", + "required": true, + "description": "The SDN route map identifier", + "format": "pve-sdn-route-map-id" + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "description": "Matching policy of a route map entry.", + "enum": [ + "permit", + "deny" + ] + }, + { + "name": "call", + "type": "string", + "required": false, + "description": "The SDN route map identifier", + "format": "pve-sdn-route-map-id" + }, + { + "name": "delete", + "type": "array", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "exit-action", + "type": "string", + "required": false + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "match", + "type": "array", + "required": false + }, + { + "name": "set", + "type": "array", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\nupdate_route_map_entry\nUpdate Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\naction string Matching policy of a route map entry. permit deny\ncall string The SDN route map identifier\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nexit-action string\nlock-token string the token for unlocking the global SDN configuration\nmatch array\nset array" + }, + { + "id": "GET /cluster/sdn/vnets", + "method": "GET", + "path": "/cluster/sdn/vnets", + "section": "cluster", + "summary": "index", + "description": "SDN vnets index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/vnets\ncluster\nindex\nSDN vnets index.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/vnets", + "method": "POST", + "path": "/cluster/sdn/vnets", + "section": "cluster", + "summary": "create", + "description": "Create a new sdn vnet object.", + "pathParameters": [], + "requestParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "Name of the zone this VNet belongs to." + }, + { + "name": "alias", + "type": "string", + "required": false, + "description": "Alias name of the VNet." + }, + { + "name": "isolate-ports", + "type": "boolean", + "required": false, + "description": "If true, sets the isolated property for all interfaces on the bridge of this VNet." + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "tag", + "type": "integer", + "required": false, + "description": "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "minimum": 1, + "maximum": 16777215 + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Type of the VNet.", + "enum": [ + "vnet" + ] + }, + { + "name": "vlanaware", + "type": "boolean", + "required": false, + "description": "Allow VLANs to pass through this vnet." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/vnets\ncluster\ncreate\nCreate a new sdn vnet object.\nvnet string The SDN vnet object identifier.\nzone string Name of the zone this VNet belongs to.\nalias string Alias name of the VNet.\nisolate-ports boolean If true, sets the isolated property for all interfaces on the bridge of this VNet.\nlock-token string the token for unlocking the global SDN configuration\ntag integer VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).\ntype string Type of the VNet. vnet\nvlanaware boolean Allow VLANs to pass through this vnet." + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}", + "section": "cluster", + "summary": "delete", + "description": "Delete sdn vnet object configuration.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}\ncluster\ndelete\nDelete sdn vnet object configuration.\nvnet string The SDN vnet object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}", + "section": "cluster", + "summary": "read", + "description": "Read sdn vnet configuration.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + } + } + }, + "permissions": { + "description": "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + } + } + }, + "searchText": "GET\n/cluster/sdn/vnets/{vnet}\ncluster\nread\nRead sdn vnet configuration.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}", + "section": "cluster", + "summary": "update", + "description": "Update sdn vnet object configuration.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "alias", + "type": "string", + "required": false, + "description": "Alias name of the VNet." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "isolate-ports", + "type": "boolean", + "required": false, + "description": "If true, sets the isolated property for all interfaces on the bridge of this VNet." + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "tag", + "type": "integer", + "required": false, + "description": "VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).", + "minimum": 1, + "maximum": 16777215 + }, + { + "name": "vlanaware", + "type": "boolean", + "required": false, + "description": "Allow VLANs to pass through this vnet." + }, + { + "name": "zone", + "type": "string", + "required": false, + "description": "Name of the zone this VNet belongs to." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}\ncluster\nupdate\nUpdate sdn vnet object configuration.\nvnet string The SDN vnet object identifier.\nalias string Alias name of the VNet.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nisolate-ports boolean If true, sets the isolated property for all interfaces on the bridge of this VNet.\nlock-token string the token for unlocking the global SDN configuration\ntag integer VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).\nvlanaware boolean Allow VLANs to pass through this vnet.\nzone string Name of the zone this VNet belongs to." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall", + "section": "cluster", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall\ncluster\nindex\nDirectory index.\nvnet string The SDN vnet object identifier." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall/options", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "section": "cluster", + "summary": "get_options", + "description": "Get vnet firewall options.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall/options\ncluster\nget_options\nGet vnet firewall options.\nvnet string The SDN vnet object identifier." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/firewall/options", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "section": "cluster", + "summary": "set_options", + "description": "Set Firewall options.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "enable", + "type": "boolean", + "required": false, + "description": "Enable/disable firewall rules.", + "default": 0 + }, + { + "name": "log_level_forward", + "type": "string", + "required": false, + "description": "Log level for forwarded traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "policy_forward", + "type": "string", + "required": false, + "description": "Forward policy.", + "enum": [ + "ACCEPT", + "DROP" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/firewall/options\ncluster\nset_options\nSet Firewall options.\nvnet string The SDN vnet object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nlog_level_forward string Log level for forwarded traffic. emerg alert crit err warning notice info debug nolog\npolicy_forward string Forward policy. ACCEPT DROP" + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall/rules", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "section": "cluster", + "summary": "get_rules", + "description": "List rules.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall/rules\ncluster\nget_rules\nList rules.\nvnet string The SDN vnet object identifier." + }, + { + "id": "POST /cluster/sdn/vnets/{vnet}/firewall/rules", + "method": "POST", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "section": "cluster", + "summary": "create_rule", + "description": "Create new rule.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/vnets/{vnet}/firewall/rules\ncluster\ncreate_rule\nCreate new rule.\nvnet string The SDN vnet object identifier.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "section": "cluster", + "summary": "delete_rule", + "description": "Delete rule.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\ndelete_rule\nDelete rule.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "section": "cluster", + "summary": "get_rule", + "description": "Get single rule data.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\nget_rule\nGet single rule data.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position ." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "section": "cluster", + "summary": "update_rule", + "description": "Modify rule data.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "moveto", + "type": "integer", + "required": false, + "description": "Move rule to new position . Other arguments are ignored.", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\nupdate_rule\nModify rule data.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}/ips", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}/ips", + "section": "cluster", + "summary": "ipdelete", + "description": "Delete IP Mappings in a VNet", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "ip", + "type": "string", + "required": true, + "description": "The IP address to delete", + "format": "ip" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + }, + { + "name": "mac", + "type": "string", + "required": false, + "description": "Unicast MAC address.", + "format": "mac-addr" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipdelete\nDelete IP Mappings in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to delete\nzone string The SDN zone object identifier.\nmac string Unicast MAC address." + }, + { + "id": "POST /cluster/sdn/vnets/{vnet}/ips", + "method": "POST", + "path": "/cluster/sdn/vnets/{vnet}/ips", + "section": "cluster", + "summary": "ipcreate", + "description": "Create IP Mapping in a VNet", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "ip", + "type": "string", + "required": true, + "description": "The IP address to associate with the given MAC address", + "format": "ip" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + }, + { + "name": "mac", + "type": "string", + "required": false, + "description": "Unicast MAC address.", + "format": "mac-addr" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipcreate\nCreate IP Mapping in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to associate with the given MAC address\nzone string The SDN zone object identifier.\nmac string Unicast MAC address." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/ips", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/ips", + "section": "cluster", + "summary": "ipupdate", + "description": "Update IP Mapping in a VNet", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "ip", + "type": "string", + "required": true, + "description": "The IP address to associate with the given MAC address", + "format": "ip" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + }, + { + "name": "mac", + "type": "string", + "required": false, + "description": "Unicast MAC address.", + "format": "mac-addr" + }, + { + "name": "vmid", + "type": "integer", + "required": false, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipupdate\nUpdate IP Mapping in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to associate with the given MAC address\nzone string The SDN zone object identifier.\nmac string Unicast MAC address.\nvmid integer The (unique) ID of the VM." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/subnets", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "section": "cluster", + "summary": "index", + "description": "SDN subnets index.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{subnet}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/subnets\ncluster\nindex\nSDN subnets index.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/vnets/{vnet}/subnets", + "method": "POST", + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "section": "cluster", + "summary": "create", + "description": "Create a new sdn subnet object.", + "pathParameters": [ + { + "name": "vnet", + "type": "string", + "required": true, + "description": "associated vnet" + } + ], + "requestParameters": [ + { + "name": "subnet", + "type": "string", + "required": true, + "description": "The SDN subnet object identifier.", + "format": "pve-sdn-subnet-id" + }, + { + "name": "type", + "type": "string", + "required": true, + "enum": [ + "subnet" + ] + }, + { + "name": "dhcp-dns-server", + "type": "string", + "required": false, + "description": "IP address for the DNS server", + "format": "ip" + }, + { + "name": "dhcp-range", + "type": "array", + "required": false, + "description": "A list of DHCP ranges for this subnet" + }, + { + "name": "dnszoneprefix", + "type": "string", + "required": false, + "description": "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format": "dns-name" + }, + { + "name": "gateway", + "type": "string", + "required": false, + "description": "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format": "ip" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "snat", + "type": "boolean", + "required": false, + "description": "enable masquerade for this subnet if pve-firewall" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/vnets/{vnet}/subnets\ncluster\ncreate\nCreate a new sdn subnet object.\nvnet string associated vnet\nsubnet string The SDN subnet object identifier.\ntype string subnet\ndhcp-dns-server string IP address for the DNS server\ndhcp-range array A list of DHCP ranges for this subnet\ndnszoneprefix string dns domain zone prefix ex: 'adm' -> .adm.mydomain.com\ngateway string Subnet Gateway: Will be assign on vnet for layer3 zones\nlock-token string the token for unlocking the global SDN configuration\nsnat boolean enable masquerade for this subnet if pve-firewall" + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "section": "cluster", + "summary": "delete", + "description": "Delete sdn subnet object configuration.", + "pathParameters": [ + { + "name": "subnet", + "type": "string", + "required": true, + "description": "The SDN subnet object identifier.", + "format": "pve-sdn-subnet-id" + }, + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\ndelete\nDelete sdn subnet object configuration.\nsubnet string The SDN subnet object identifier.\nvnet string The SDN vnet object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "section": "cluster", + "summary": "read", + "description": "Read sdn subnet configuration.", + "pathParameters": [ + { + "name": "subnet", + "type": "string", + "required": true, + "description": "The SDN subnet object identifier.", + "format": "pve-sdn-subnet-id" + }, + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "returns": { + "type": "object" + }, + "permissions": { + "description": "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\nread\nRead sdn subnet configuration.\nsubnet string The SDN subnet object identifier.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "section": "cluster", + "summary": "update", + "description": "Update sdn subnet object configuration.", + "pathParameters": [ + { + "name": "subnet", + "type": "string", + "required": true, + "description": "The SDN subnet object identifier.", + "format": "pve-sdn-subnet-id" + }, + { + "name": "vnet", + "type": "string", + "required": false, + "description": "associated vnet" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dhcp-dns-server", + "type": "string", + "required": false, + "description": "IP address for the DNS server", + "format": "ip" + }, + { + "name": "dhcp-range", + "type": "array", + "required": false, + "description": "A list of DHCP ranges for this subnet" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dnszoneprefix", + "type": "string", + "required": false, + "description": "dns domain zone prefix ex: 'adm' -> .adm.mydomain.com", + "format": "dns-name" + }, + { + "name": "gateway", + "type": "string", + "required": false, + "description": "Subnet Gateway: Will be assign on vnet for layer3 zones", + "format": "ip" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "snat", + "type": "boolean", + "required": false, + "description": "enable masquerade for this subnet if pve-firewall" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\nupdate\nUpdate sdn subnet object configuration.\nsubnet string The SDN subnet object identifier.\nvnet string associated vnet\ndelete string A list of settings you want to delete.\ndhcp-dns-server string IP address for the DNS server\ndhcp-range array A list of DHCP ranges for this subnet\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndnszoneprefix string dns domain zone prefix ex: 'adm' -> .adm.mydomain.com\ngateway string Subnet Gateway: Will be assign on vnet for layer3 zones\nlock-token string the token for unlocking the global SDN configuration\nsnat boolean enable masquerade for this subnet if pve-firewall" + }, + { + "id": "GET /cluster/sdn/zones", + "method": "GET", + "path": "/cluster/sdn/zones", + "section": "cluster", + "summary": "index", + "description": "SDN zones index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list SDN zones of specific type", + "enum": [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ] + } + ], + "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" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/sdn/zones\ncluster\nindex\nSDN zones index.\npending boolean Display pending config.\nrunning boolean Display running config.\ntype string Only list SDN zones of specific type evpn faucet qinq simple vlan vxlan" + }, + { + "id": "POST /cluster/sdn/zones", + "method": "POST", + "path": "/cluster/sdn/zones", + "section": "cluster", + "summary": "create", + "description": "Create a new sdn zone object.", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": true, + "description": "Plugin type.", + "enum": [ + "evpn", + "faucet", + "qinq", + "simple", + "vlan", + "vxlan" + ], + "format": "pve-configid" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + }, + { + "name": "advertise-subnets", + "type": "boolean", + "required": false, + "description": "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes)." + }, + { + "name": "bridge", + "type": "string", + "required": false, + "description": "The bridge for which VLANs should be managed." + }, + { + "name": "bridge-disable-mac-learning", + "type": "boolean", + "required": false, + "description": "Disable auto mac learning." + }, + { + "name": "controller", + "type": "string", + "required": false, + "description": "Controller for this zone." + }, + { + "name": "dhcp", + "type": "string", + "required": false, + "description": "Type of the DHCP backend for this zone", + "enum": [ + "dnsmasq" + ] + }, + { + "name": "disable-arp-nd-suppression", + "type": "boolean", + "required": false, + "description": "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages." + }, + { + "name": "dns", + "type": "string", + "required": false, + "description": "dns api server" + }, + { + "name": "dnszone", + "type": "string", + "required": false, + "description": "dns domain zone ex: mydomain.com", + "format": "dns-name" + }, + { + "name": "dp-id", + "type": "integer", + "required": false, + "description": "Faucet dataplane id" + }, + { + "name": "exitnodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "exitnodes-local-routing", + "type": "boolean", + "required": false, + "description": "Allow exitnodes to connect to EVPN guests." + }, + { + "name": "exitnodes-primary", + "type": "string", + "required": false, + "description": "Force traffic through this exitnode first.", + "format": "pve-node" + }, + { + "name": "fabric", + "type": "string", + "required": false, + "description": "SDN fabric to use as underlay for this VXLAN zone.", + "format": "pve-sdn-fabric-id" + }, + { + "name": "ipam", + "type": "string", + "required": false, + "description": "use a specific ipam" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "mac", + "type": "string", + "required": false, + "description": "Anycast logical router mac address.", + "format": "mac-addr" + }, + { + "name": "mtu", + "type": "integer", + "required": false, + "description": "MTU of the zone, will be used for the created VNet bridges." + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "peers", + "type": "string", + "required": false, + "description": "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.", + "format": "ip-list" + }, + { + "name": "reversedns", + "type": "string", + "required": false, + "description": "reverse dns api server" + }, + { + "name": "rt-import", + "type": "string", + "required": false, + "description": "List of Route Targets that should be imported into the VRF of the zone.", + "format": "pve-sdn-bgp-rt-list" + }, + { + "name": "secondary-controllers", + "type": "array", + "required": false, + "description": "Additional controllers." + }, + { + "name": "tag", + "type": "integer", + "required": false, + "description": "Service-VLAN Tag (outer VLAN)", + "minimum": 0 + }, + { + "name": "vlan-protocol", + "type": "string", + "required": false, + "description": "Which VLAN protocol should be used for the creation of the QinQ zone.", + "enum": [ + "802.1q", + "802.1ad" + ], + "default": "802.1q" + }, + { + "name": "vrf-vxlan", + "type": "integer", + "required": false, + "description": "VNI for the zone VRF.", + "minimum": 1, + "maximum": 16777215 + }, + { + "name": "vxlan-port", + "type": "integer", + "required": false, + "description": "UDP port that should be used for the VXLAN tunnel (default 4789).", + "default": 4789, + "minimum": 1, + "maximum": 65536 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/cluster/sdn/zones\ncluster\ncreate\nCreate a new sdn zone object.\ntype string Plugin type. evpn faucet qinq simple vlan vxlan\nzone string The SDN zone object identifier.\nadvertise-subnets boolean Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).\nbridge string The bridge for which VLANs should be managed.\nbridge-disable-mac-learning boolean Disable auto mac learning.\ncontroller string Controller for this zone.\ndhcp string Type of the DHCP backend for this zone dnsmasq\ndisable-arp-nd-suppression boolean Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.\ndns string dns api server\ndnszone string dns domain zone ex: mydomain.com\ndp-id integer Faucet dataplane id\nexitnodes string List of cluster node names.\nexitnodes-local-routing boolean Allow exitnodes to connect to EVPN guests.\nexitnodes-primary string Force traffic through this exitnode first.\nfabric string SDN fabric to use as underlay for this VXLAN zone.\nipam string use a specific ipam\nlock-token string the token for unlocking the global SDN configuration\nmac string Anycast logical router mac address.\nmtu integer MTU of the zone, will be used for the created VNet bridges.\nnodes string List of cluster node names.\npeers string Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.\nreversedns string reverse dns api server\nrt-import string List of Route Targets that should be imported into the VRF of the zone.\nsecondary-controllers array Additional controllers.\ntag integer Service-VLAN Tag (outer VLAN)\nvlan-protocol string Which VLAN protocol should be used for the creation of the QinQ zone. 802.1q 802.1ad\nvrf-vxlan integer VNI for the zone VRF.\nvxlan-port integer UDP port that should be used for the VXLAN tunnel (default 4789)." + }, + { + "id": "DELETE /cluster/sdn/zones/{zone}", + "method": "DELETE", + "path": "/cluster/sdn/zones/{zone}", + "section": "cluster", + "summary": "delete", + "description": "Delete sdn zone object configuration.", + "pathParameters": [ + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + } + ], + "requestParameters": [ + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/cluster/sdn/zones/{zone}\ncluster\ndelete\nDelete sdn zone object configuration.\nzone string The SDN zone object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/zones/{zone}", + "method": "GET", + "path": "/cluster/sdn/zones/{zone}", + "section": "cluster", + "summary": "read", + "description": "Read sdn zone configuration.", + "pathParameters": [ + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + } + ], + "requestParameters": [ + { + "name": "pending", + "type": "boolean", + "required": false, + "description": "Display pending config." + }, + { + "name": "running", + "type": "boolean", + "required": false, + "description": "Display running config." + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "GET\n/cluster/sdn/zones/{zone}\ncluster\nread\nRead sdn zone configuration.\nzone string The SDN zone object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/zones/{zone}", + "method": "PUT", + "path": "/cluster/sdn/zones/{zone}", + "section": "cluster", + "summary": "update", + "description": "Update sdn zone object configuration.", + "pathParameters": [ + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + } + ], + "requestParameters": [ + { + "name": "advertise-subnets", + "type": "boolean", + "required": false, + "description": "Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes)." + }, + { + "name": "bridge", + "type": "string", + "required": false, + "description": "The bridge for which VLANs should be managed." + }, + { + "name": "bridge-disable-mac-learning", + "type": "boolean", + "required": false, + "description": "Disable auto mac learning." + }, + { + "name": "controller", + "type": "string", + "required": false, + "description": "Controller for this zone." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dhcp", + "type": "string", + "required": false, + "description": "Type of the DHCP backend for this zone", + "enum": [ + "dnsmasq" + ] + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable-arp-nd-suppression", + "type": "boolean", + "required": false, + "description": "Suppress IPv4 ARP && IPv6 Neighbour Discovery messages." + }, + { + "name": "dns", + "type": "string", + "required": false, + "description": "dns api server" + }, + { + "name": "dnszone", + "type": "string", + "required": false, + "description": "dns domain zone ex: mydomain.com", + "format": "dns-name" + }, + { + "name": "dp-id", + "type": "integer", + "required": false, + "description": "Faucet dataplane id" + }, + { + "name": "exitnodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "exitnodes-local-routing", + "type": "boolean", + "required": false, + "description": "Allow exitnodes to connect to EVPN guests." + }, + { + "name": "exitnodes-primary", + "type": "string", + "required": false, + "description": "Force traffic through this exitnode first.", + "format": "pve-node" + }, + { + "name": "fabric", + "type": "string", + "required": false, + "description": "SDN fabric to use as underlay for this VXLAN zone.", + "format": "pve-sdn-fabric-id" + }, + { + "name": "ipam", + "type": "string", + "required": false, + "description": "use a specific ipam" + }, + { + "name": "lock-token", + "type": "string", + "required": false, + "description": "the token for unlocking the global SDN configuration" + }, + { + "name": "mac", + "type": "string", + "required": false, + "description": "Anycast logical router mac address.", + "format": "mac-addr" + }, + { + "name": "mtu", + "type": "integer", + "required": false, + "description": "MTU of the zone, will be used for the created VNet bridges." + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of cluster node names.", + "format": "pve-node-list" + }, + { + "name": "peers", + "type": "string", + "required": false, + "description": "Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.", + "format": "ip-list" + }, + { + "name": "reversedns", + "type": "string", + "required": false, + "description": "reverse dns api server" + }, + { + "name": "rt-import", + "type": "string", + "required": false, + "description": "List of Route Targets that should be imported into the VRF of the zone.", + "format": "pve-sdn-bgp-rt-list" + }, + { + "name": "secondary-controllers", + "type": "array", + "required": false, + "description": "Additional controllers." + }, + { + "name": "tag", + "type": "integer", + "required": false, + "description": "Service-VLAN Tag (outer VLAN)", + "minimum": 0 + }, + { + "name": "vlan-protocol", + "type": "string", + "required": false, + "description": "Which VLAN protocol should be used for the creation of the QinQ zone.", + "enum": [ + "802.1q", + "802.1ad" + ], + "default": "802.1q" + }, + { + "name": "vrf-vxlan", + "type": "integer", + "required": false, + "description": "VNI for the zone VRF.", + "minimum": 1, + "maximum": 16777215 + }, + { + "name": "vxlan-port", + "type": "integer", + "required": false, + "description": "UDP port that should be used for the VXLAN tunnel (default 4789).", + "default": 4789, + "minimum": 1, + "maximum": 65536 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/cluster/sdn/zones/{zone}\ncluster\nupdate\nUpdate sdn zone object configuration.\nzone string The SDN zone object identifier.\nadvertise-subnets boolean Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).\nbridge string The bridge for which VLANs should be managed.\nbridge-disable-mac-learning boolean Disable auto mac learning.\ncontroller string Controller for this zone.\ndelete string A list of settings you want to delete.\ndhcp string Type of the DHCP backend for this zone dnsmasq\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable-arp-nd-suppression boolean Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.\ndns string dns api server\ndnszone string dns domain zone ex: mydomain.com\ndp-id integer Faucet dataplane id\nexitnodes string List of cluster node names.\nexitnodes-local-routing boolean Allow exitnodes to connect to EVPN guests.\nexitnodes-primary string Force traffic through this exitnode first.\nfabric string SDN fabric to use as underlay for this VXLAN zone.\nipam string use a specific ipam\nlock-token string the token for unlocking the global SDN configuration\nmac string Anycast logical router mac address.\nmtu integer MTU of the zone, will be used for the created VNet bridges.\nnodes string List of cluster node names.\npeers string Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.\nreversedns string reverse dns api server\nrt-import string List of Route Targets that should be imported into the VRF of the zone.\nsecondary-controllers array Additional controllers.\ntag integer Service-VLAN Tag (outer VLAN)\nvlan-protocol string Which VLAN protocol should be used for the creation of the QinQ zone. 802.1q 802.1ad\nvrf-vxlan integer VNI for the zone VRF.\nvxlan-port integer UDP port that should be used for the VXLAN tunnel (default 4789)." + }, + { + "id": "GET /cluster/status", + "method": "GET", + "path": "/cluster/status", + "section": "cluster", + "summary": "get_status", + "description": "Get cluster status information.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/status\ncluster\nget_status\nGet cluster status information." + }, + { + "id": "GET /cluster/tasks", + "method": "GET", + "path": "/cluster/tasks", + "section": "cluster", + "summary": "tasks", + "description": "List recent tasks (cluster wide).", + "pathParameters": [], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "upid": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/cluster/tasks\ncluster\ntasks\nList recent tasks (cluster wide)." + }, + { + "id": "GET /nodes", + "method": "GET", + "path": "/nodes", + "section": "nodes", + "summary": "index", + "description": "Cluster node index.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes\nnodes\nindex\nCluster node index." + }, + { + "id": "GET /nodes/{node}", + "method": "GET", + "path": "/nodes/{node}", + "section": "nodes", + "summary": "index", + "description": "Node index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}\nnodes\nindex\nNode index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/aplinfo", + "method": "GET", + "path": "/nodes/{node}/aplinfo", + "section": "nodes", + "summary": "aplinfo", + "description": "Get list of appliances.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/aplinfo\nnodes\naplinfo\nGet list of appliances.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/aplinfo", + "method": "POST", + "path": "/nodes/{node}/aplinfo", + "section": "nodes", + "summary": "apl_download", + "description": "Download appliance templates.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage where the template will be stored", + "format": "pve-storage-id" + }, + { + "name": "template", + "type": "string", + "required": true, + "description": "The template which will downloaded" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/aplinfo\nnodes\napl_download\nDownload appliance templates.\nnode string The cluster node name.\nstorage string The storage where the template will be stored\ntemplate string The template which will downloaded" + }, + { + "id": "GET /nodes/{node}/apt", + "method": "GET", + "path": "/nodes/{node}/apt", + "section": "nodes", + "summary": "index", + "description": "Directory index for apt (Advanced Package Tool).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/apt\nnodes\nindex\nDirectory index for apt (Advanced Package Tool).\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/apt/changelog", + "method": "GET", + "path": "/nodes/{node}/apt/changelog", + "section": "nodes", + "summary": "changelog", + "description": "Get package changelogs.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Package name." + }, + { + "name": "version", + "type": "string", + "required": false, + "description": "Package version." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/apt/changelog\nnodes\nchangelog\nGet package changelogs.\nnode string The cluster node name.\nname string Package name.\nversion string Package version." + }, + { + "id": "GET /nodes/{node}/apt/repositories", + "method": "GET", + "path": "/nodes/{node}/apt/repositories", + "section": "nodes", + "summary": "repositories", + "description": "Get APT repository information.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/apt/repositories\nnodes\nrepositories\nGet APT repository information.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/apt/repositories", + "method": "POST", + "path": "/nodes/{node}/apt/repositories", + "section": "nodes", + "summary": "change_repository", + "description": "Change the properties of a repository. Currently only allows enabling/disabling.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "index", + "type": "integer", + "required": true, + "description": "Index within the file (starting from 0)." + }, + { + "name": "path", + "type": "string", + "required": true, + "description": "Path to the containing file." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Digest to detect modifications." + }, + { + "name": "enabled", + "type": "boolean", + "required": false, + "description": "Whether the repository should be enabled or not." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/apt/repositories\nnodes\nchange_repository\nChange the properties of a repository. Currently only allows enabling/disabling.\nnode string The cluster node name.\nindex integer Index within the file (starting from 0).\npath string Path to the containing file.\ndigest string Digest to detect modifications.\nenabled boolean Whether the repository should be enabled or not." + }, + { + "id": "PUT /nodes/{node}/apt/repositories", + "method": "PUT", + "path": "/nodes/{node}/apt/repositories", + "section": "nodes", + "summary": "add_repository", + "description": "Add a standard repository to the configuration", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "handle", + "type": "string", + "required": true, + "description": "Handle that identifies a repository." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Digest to detect modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/apt/repositories\nnodes\nadd_repository\nAdd a standard repository to the configuration\nnode string The cluster node name.\nhandle string Handle that identifies a repository.\ndigest string Digest to detect modifications." + }, + { + "id": "GET /nodes/{node}/apt/update", + "method": "GET", + "path": "/nodes/{node}/apt/update", + "section": "nodes", + "summary": "list_updates", + "description": "List available updates.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/apt/update\nnodes\nlist_updates\nList available updates.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/apt/update", + "method": "POST", + "path": "/nodes/{node}/apt/update", + "section": "nodes", + "summary": "update_database", + "description": "This is used to resynchronize the package index files from their sources (apt-get update).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "notify", + "type": "boolean", + "required": false, + "description": "Send notification about new packages.", + "default": 0 + }, + { + "name": "quiet", + "type": "boolean", + "required": false, + "description": "Only produces output suitable for logging, omitting progress indicators.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/apt/update\nnodes\nupdate_database\nThis is used to resynchronize the package index files from their sources (apt-get update).\nnode string The cluster node name.\nnotify boolean Send notification about new packages.\nquiet boolean Only produces output suitable for logging, omitting progress indicators." + }, + { + "id": "GET /nodes/{node}/apt/versions", + "method": "GET", + "path": "/nodes/{node}/apt/versions", + "section": "nodes", + "summary": "versions", + "description": "Get package information for important Proxmox packages.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/apt/versions\nnodes\nversions\nGet package information for important Proxmox packages.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/capabilities", + "method": "GET", + "path": "/nodes/{node}/capabilities", + "section": "nodes", + "summary": "index", + "description": "Node capabilities index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/capabilities\nnodes\nindex\nNode capabilities index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/capabilities/qemu", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu", + "section": "nodes", + "summary": "qemu_caps_index", + "description": "QEMU capabilities index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/capabilities/qemu\nnodes\nqemu_caps_index\nQEMU capabilities index.\nnode string The cluster node name.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/cpu", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/cpu", + "section": "nodes", + "summary": "index", + "description": "List all custom and default CPU models.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "arch", + "type": "string", + "required": false, + "description": "Virtual processor architecture. Defaults to the host architecture.", + "enum": [ + "x86_64", + "aarch64" + ] + } + ], + "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" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/capabilities/qemu/cpu\nnodes\nindex\nList all custom and default CPU models.\nnode string The cluster node name.\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/cpu-flags", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/cpu-flags", + "section": "nodes", + "summary": "index", + "description": "List of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "accel", + "type": "string", + "required": false, + "description": "Acceleration type to check node compatibility for.", + "enum": [ + "kvm", + "tcg" + ], + "default": "kvm" + }, + { + "name": "arch", + "type": "string", + "required": false, + "description": "Virtual processor architecture. Defaults to the host architecture.", + "enum": [ + "x86_64", + "aarch64" + ] + } + ], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/capabilities/qemu/cpu-flags\nnodes\nindex\nList of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet.\nnode string The cluster node name.\naccel string Acceleration type to check node compatibility for. kvm tcg\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/machines", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/machines", + "section": "nodes", + "summary": "types", + "description": "Get available QEMU/KVM machine types.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "arch", + "type": "string", + "required": false, + "description": "Virtual processor architecture. Defaults to the host architecture.", + "enum": [ + "x86_64", + "aarch64" + ] + } + ], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/capabilities/qemu/machines\nnodes\ntypes\nGet available QEMU/KVM machine types.\nnode string The cluster node name.\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/migration", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/migration", + "section": "nodes", + "summary": "capabilities", + "description": "Get node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/capabilities/qemu/migration\nnodes\ncapabilities\nGet node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'.\nnode string The cluster node name.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/ceph", + "method": "GET", + "path": "/nodes/{node}/ceph", + "section": "nodes", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg", + "section": "nodes", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/cfg\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg/db", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg/db", + "section": "nodes", + "summary": "db", + "description": "Get the Ceph configuration database.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/cfg/db\nnodes\ndb\nGet the Ceph configuration database.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg/raw", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg/raw", + "section": "nodes", + "summary": "raw", + "description": "Get the Ceph configuration file.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/cfg/raw\nnodes\nraw\nGet the Ceph configuration file.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg/value", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg/value", + "section": "nodes", + "summary": "value", + "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.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "config-keys", + "type": "string", + "required": true, + "description": "List of
: items separated by semicolon, comma or space." + } + ], + "returns": { + "description": "Two-level map of {section} -> {key} -> value. Underscores in section and key names are normalised to hyphens.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/cfg/value\nnodes\nvalue\nGet 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.\nnode string The cluster node name.\nconfig-keys string List of
: items separated by semicolon, comma or space." + }, + { + "id": "GET /nodes/{node}/ceph/cmd-safety", + "method": "GET", + "path": "/nodes/{node}/ceph/cmd-safety", + "section": "nodes", + "summary": "cmd_safety", + "description": "Heuristical check if it is safe to perform an action.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Action to check", + "enum": [ + "stop", + "destroy" + ] + }, + { + "name": "id", + "type": "string", + "required": true, + "description": "ID of the service" + }, + { + "name": "service", + "type": "string", + "required": true, + "description": "Service type", + "enum": [ + "osd", + "mon", + "mds" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/cmd-safety\nnodes\ncmd_safety\nHeuristical check if it is safe to perform an action.\nnode string The cluster node name.\naction string Action to check stop destroy\nid string ID of the service\nservice string Service type osd mon mds" + }, + { + "id": "GET /nodes/{node}/ceph/crush", + "method": "GET", + "path": "/nodes/{node}/ceph/crush", + "section": "nodes", + "summary": "crush", + "description": "Get OSD crush map", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/crush\nnodes\ncrush\nGet OSD crush map\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/fs", + "method": "GET", + "path": "/nodes/{node}/ceph/fs", + "section": "nodes", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/fs\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/fs/{name}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/fs/{name}", + "section": "nodes", + "summary": "destroyfs", + "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.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The Ceph filesystem name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "remove-pools", + "type": "boolean", + "required": false, + "description": "Remove the metadata and data pools used by this filesystem.", + "default": 0 + }, + { + "name": "remove-storages", + "type": "boolean", + "required": false, + "description": "Remove pveceph-managed storages configured for this filesystem.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/ceph/fs/{name}\nnodes\ndestroyfs\nDestroy 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.\nname string The Ceph filesystem name.\nnode string The cluster node name.\nremove-pools boolean Remove the metadata and data pools used by this filesystem.\nremove-storages boolean Remove pveceph-managed storages configured for this filesystem." + }, + { + "id": "POST /nodes/{node}/ceph/fs/{name}", + "method": "POST", + "path": "/nodes/{node}/ceph/fs/{name}", + "section": "nodes", + "summary": "createfs", + "description": "Create a Ceph filesystem", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "The ceph filesystem name.", + "default": "cephfs" + } + ], + "requestParameters": [ + { + "name": "add-storage", + "type": "boolean", + "required": false, + "description": "Configure the created CephFS as storage for this cluster.", + "default": 0 + }, + { + "name": "pg_num", + "type": "integer", + "required": false, + "description": "Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.", + "default": 128, + "minimum": 8, + "maximum": 32768 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/fs/{name}\nnodes\ncreatefs\nCreate a Ceph filesystem\nnode string The cluster node name.\nname string The ceph filesystem name.\nadd-storage boolean Configure the created CephFS as storage for this cluster.\npg_num integer Number of placement groups for the backing data pool. The metadata pool will use a quarter of this." + }, + { + "id": "POST /nodes/{node}/ceph/init", + "method": "POST", + "path": "/nodes/{node}/ceph/init", + "section": "nodes", + "summary": "init", + "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.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "cluster-network", + "type": "string", + "required": false, + "description": "Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it", + "format": "CIDR" + }, + { + "name": "disable_cephx", + "type": "boolean", + "required": false, + "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!", + "default": 0 + }, + { + "name": "min_size", + "type": "integer", + "required": false, + "description": "Minimum number of available replicas per object to allow I/O", + "default": 2, + "minimum": 1, + "maximum": 7 + }, + { + "name": "network", + "type": "string", + "required": false, + "description": "Use specific network for all ceph related traffic", + "format": "CIDR" + }, + { + "name": "pg_bits", + "type": "integer", + "required": false, + "description": "Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.", + "default": 6, + "minimum": 6, + "maximum": 14 + }, + { + "name": "size", + "type": "integer", + "required": false, + "description": "Targeted number of replicas per object", + "default": 3, + "minimum": 1, + "maximum": 7 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/init\nnodes\ninit\nCreate 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.\nnode string The cluster node name.\ncluster-network string Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it\ndisable_cephx boolean 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!\nmin_size integer Minimum number of available replicas per object to allow I/O\nnetwork string Use specific network for all ceph related traffic\npg_bits integer Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.\nsize integer Targeted number of replicas per object" + }, + { + "id": "GET /nodes/{node}/ceph/log", + "method": "GET", + "path": "/nodes/{node}/ceph/log", + "section": "nodes", + "summary": "log", + "description": "Read ceph log", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "limit", + "type": "integer", + "required": false, + "description": "Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted.", + "minimum": 0 + }, + { + "name": "start", + "type": "integer", + "required": false, + "description": "Offset of the first log line to return (0-based).", + "minimum": 0 + } + ], + "returns": { + "items": { + "properties": { + "n": { + "description": "Log-file line number (1-based).", + "type": "integer" + }, + "t": { + "description": "Log line text.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/log\nnodes\nlog\nRead ceph log\nnode string The cluster node name.\nlimit integer Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted.\nstart integer Offset of the first log line to return (0-based)." + }, + { + "id": "GET /nodes/{node}/ceph/mds", + "method": "GET", + "path": "/nodes/{node}/ceph/mds", + "section": "nodes", + "summary": "index", + "description": "MDS directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/mds\nnodes\nindex\nMDS directory index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/mds/{name}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/mds/{name}", + "section": "nodes", + "summary": "destroymds", + "description": "Destroy Ceph Metadata Server", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name (ID) of the mds" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/ceph/mds/{name}\nnodes\ndestroymds\nDestroy Ceph Metadata Server\nname string The name (ID) of the mds\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/mds/{name}", + "method": "POST", + "path": "/nodes/{node}/ceph/mds/{name}", + "section": "nodes", + "summary": "createmds", + "description": "Create Ceph Metadata Server (MDS)", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "The ID for the mds, when omitted the same as the nodename", + "default": "nodename" + } + ], + "requestParameters": [ + { + "name": "hotstandby", + "type": "boolean", + "required": false, + "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.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/mds/{name}\nnodes\ncreatemds\nCreate Ceph Metadata Server (MDS)\nnode string The cluster node name.\nname string The ID for the mds, when omitted the same as the nodename\nhotstandby boolean 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." + }, + { + "id": "GET /nodes/{node}/ceph/mgr", + "method": "GET", + "path": "/nodes/{node}/ceph/mgr", + "section": "nodes", + "summary": "index", + "description": "MGR directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/mgr\nnodes\nindex\nMGR directory index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/mgr/{id}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/mgr/{id}", + "section": "nodes", + "summary": "destroymgr", + "description": "Destroy Ceph Manager.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "description": "The ID of the manager" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/ceph/mgr/{id}\nnodes\ndestroymgr\nDestroy Ceph Manager.\nid string The ID of the manager\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/mgr/{id}", + "method": "POST", + "path": "/nodes/{node}/ceph/mgr/{id}", + "section": "nodes", + "summary": "createmgr", + "description": "Create Ceph Manager", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "id", + "type": "string", + "required": false, + "description": "The ID for the manager, when omitted the same as the nodename.", + "default": "nodename" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/mgr/{id}\nnodes\ncreatemgr\nCreate Ceph Manager\nnode string The cluster node name.\nid string The ID for the manager, when omitted the same as the nodename." + }, + { + "id": "GET /nodes/{node}/ceph/mon", + "method": "GET", + "path": "/nodes/{node}/ceph/mon", + "section": "nodes", + "summary": "listmon", + "description": "Get Ceph monitor list.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/mon\nnodes\nlistmon\nGet Ceph monitor list.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/mon/{monid}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/mon/{monid}", + "section": "nodes", + "summary": "destroymon", + "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.", + "pathParameters": [ + { + "name": "monid", + "type": "string", + "required": true, + "description": "Monitor ID" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/ceph/mon/{monid}\nnodes\ndestroymon\nDestroy 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.\nmonid string Monitor ID\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/mon/{monid}", + "method": "POST", + "path": "/nodes/{node}/ceph/mon/{monid}", + "section": "nodes", + "summary": "createmon", + "description": "Create a Ceph Monitor. Also auto-creates a Manager for the first monitor.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "monid", + "type": "string", + "required": false, + "description": "The ID for the monitor, when omitted the same as the nodename.", + "default": "nodename" + } + ], + "requestParameters": [ + { + "name": "mon-address", + "type": "string", + "required": false, + "description": "Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.", + "format": "ip-list" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/mon/{monid}\nnodes\ncreatemon\nCreate a Ceph Monitor. Also auto-creates a Manager for the first monitor.\nnode string The cluster node name.\nmonid string The ID for the monitor, when omitted the same as the nodename.\nmon-address string Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph." + }, + { + "id": "GET /nodes/{node}/ceph/osd", + "method": "GET", + "path": "/nodes/{node}/ceph/osd", + "section": "nodes", + "summary": "index", + "description": "Get Ceph osd list/tree.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/osd\nnodes\nindex\nGet Ceph osd list/tree.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/osd", + "method": "POST", + "path": "/nodes/{node}/ceph/osd", + "section": "nodes", + "summary": "createosd", + "description": "Create OSD", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "dev", + "type": "string", + "required": true, + "description": "Block device name." + }, + { + "name": "crush-device-class", + "type": "string", + "required": false, + "description": "Set the device class of the OSD in crush." + }, + { + "name": "db_dev", + "type": "string", + "required": false, + "description": "Block device name for block.db." + }, + { + "name": "db_dev_size", + "type": "number", + "required": false, + "description": "Size in GiB for block.db.", + "minimum": 1 + }, + { + "name": "encrypted", + "type": "boolean", + "required": false, + "description": "Enables encryption of the OSD.", + "default": 0 + }, + { + "name": "osds-per-device", + "type": "integer", + "required": false, + "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 + }, + { + "name": "wal_dev", + "type": "string", + "required": false, + "description": "Block device name for block.wal." + }, + { + "name": "wal_dev_size", + "type": "number", + "required": false, + "description": "Size in GiB for block.wal.", + "minimum": 0.5 + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/osd\nnodes\ncreateosd\nCreate OSD\nnode string The cluster node name.\ndev string Block device name.\ncrush-device-class string Set the device class of the OSD in crush.\ndb_dev string Block device name for block.db.\ndb_dev_size number Size in GiB for block.db.\nencrypted boolean Enables encryption of the OSD.\nosds-per-device integer OSD services per physical device. Only useful for fast NVMe devices to utilize their performance better. Mutually exclusive with 'db_dev' and 'wal_dev'.\nwal_dev string Block device name for block.wal.\nwal_dev_size number Size in GiB for block.wal." + }, + { + "id": "DELETE /nodes/{node}/ceph/osd/{osdid}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/osd/{osdid}", + "section": "nodes", + "summary": "destroyosd", + "description": "Destroy OSD", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "osdid", + "type": "integer", + "required": true, + "description": "OSD ID" + } + ], + "requestParameters": [ + { + "name": "cleanup", + "type": "boolean", + "required": false, + "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.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/ceph/osd/{osdid}\nnodes\ndestroyosd\nDestroy OSD\nnode string The cluster node name.\nosdid integer OSD ID\ncleanup boolean 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." + }, + { + "id": "GET /nodes/{node}/ceph/osd/{osdid}", + "method": "GET", + "path": "/nodes/{node}/ceph/osd/{osdid}", + "section": "nodes", + "summary": "osdindex", + "description": "OSD index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "osdid", + "type": "integer", + "required": true, + "description": "OSD ID" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/osd/{osdid}\nnodes\nosdindex\nOSD index.\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "POST /nodes/{node}/ceph/osd/{osdid}/in", + "method": "POST", + "path": "/nodes/{node}/ceph/osd/{osdid}/in", + "section": "nodes", + "summary": "in", + "description": "ceph osd in", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "osdid", + "type": "integer", + "required": true, + "description": "OSD ID" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/osd/{osdid}/in\nnodes\nin\nceph osd in\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "GET /nodes/{node}/ceph/osd/{osdid}/lv-info", + "method": "GET", + "path": "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "section": "nodes", + "summary": "osdvolume", + "description": "Get OSD volume details", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "osdid", + "type": "integer", + "required": true, + "description": "OSD ID" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "OSD device type", + "enum": [ + "block", + "db", + "wal" + ], + "default": "block" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/osd/{osdid}/lv-info\nnodes\nosdvolume\nGet OSD volume details\nnode string The cluster node name.\nosdid integer OSD ID\ntype string OSD device type block db wal" + }, + { + "id": "GET /nodes/{node}/ceph/osd/{osdid}/metadata", + "method": "GET", + "path": "/nodes/{node}/ceph/osd/{osdid}/metadata", + "section": "nodes", + "summary": "osddetails", + "description": "Get OSD details", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "osdid", + "type": "integer", + "required": true, + "description": "OSD ID" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/osd/{osdid}/metadata\nnodes\nosddetails\nGet OSD details\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "POST /nodes/{node}/ceph/osd/{osdid}/out", + "method": "POST", + "path": "/nodes/{node}/ceph/osd/{osdid}/out", + "section": "nodes", + "summary": "out", + "description": "ceph osd out", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "osdid", + "type": "integer", + "required": true, + "description": "OSD ID" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/osd/{osdid}/out\nnodes\nout\nceph osd out\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "POST /nodes/{node}/ceph/osd/{osdid}/scrub", + "method": "POST", + "path": "/nodes/{node}/ceph/osd/{osdid}/scrub", + "section": "nodes", + "summary": "scrub", + "description": "Instruct the OSD to scrub.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "osdid", + "type": "integer", + "required": true, + "description": "OSD ID" + } + ], + "requestParameters": [ + { + "name": "deep", + "type": "boolean", + "required": false, + "description": "If set, instructs a deep scrub instead of a normal one.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/osd/{osdid}/scrub\nnodes\nscrub\nInstruct the OSD to scrub.\nnode string The cluster node name.\nosdid integer OSD ID\ndeep boolean If set, instructs a deep scrub instead of a normal one." + }, + { + "id": "GET /nodes/{node}/ceph/pool", + "method": "GET", + "path": "/nodes/{node}/ceph/pool", + "section": "nodes", + "summary": "lspools", + "description": "List all pools and their settings (which are settable by the POST/PUT endpoints).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/pool\nnodes\nlspools\nList all pools and their settings (which are settable by the POST/PUT endpoints).\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/pool", + "method": "POST", + "path": "/nodes/{node}/ceph/pool", + "section": "nodes", + "summary": "createpool", + "description": "Create Ceph pool", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the pool. It must be unique." + }, + { + "name": "add_storages", + "type": "boolean", + "required": false, + "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).", + "default": 0 + }, + { + "name": "application", + "type": "string", + "required": false, + "description": "The application of the pool.", + "enum": [ + "rbd", + "cephfs", + "rgw" + ], + "default": "rbd" + }, + { + "name": "crush_rule", + "type": "string", + "required": false, + "description": "The rule to use for mapping object placement in the cluster." + }, + { + "name": "erasure-coding", + "type": "string", + "required": false, + "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." + }, + { + "name": "min_size", + "type": "integer", + "required": false, + "description": "Minimum number of replicas per object", + "default": 2, + "minimum": 1, + "maximum": 7 + }, + { + "name": "pg_autoscale_mode", + "type": "string", + "required": false, + "description": "The automatic PG scaling mode of the pool.", + "enum": [ + "on", + "off", + "warn" + ], + "default": "warn" + }, + { + "name": "pg_num", + "type": "integer", + "required": false, + "description": "Number of placement groups.", + "default": 128, + "minimum": 1, + "maximum": 32768 + }, + { + "name": "pg_num_min", + "type": "integer", + "required": false, + "description": "Minimal number of placement groups.", + "maximum": 32768 + }, + { + "name": "size", + "type": "integer", + "required": false, + "description": "Number of replicas per object", + "default": 3, + "minimum": 1, + "maximum": 7 + }, + { + "name": "target_size", + "type": "string", + "required": false, + "description": "The estimated target size of the pool for the PG autoscaler." + }, + { + "name": "target_size_ratio", + "type": "number", + "required": false, + "description": "The estimated target ratio of the pool for the PG autoscaler." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/pool\nnodes\ncreatepool\nCreate Ceph pool\nnode string The cluster node name.\nname string The name of the pool. It must be unique.\nadd_storages boolean 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).\napplication string The application of the pool. rbd cephfs rgw\ncrush_rule string The rule to use for mapping object placement in the cluster.\nerasure-coding string 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.\nmin_size integer Minimum number of replicas per object\npg_autoscale_mode string The automatic PG scaling mode of the pool. on off warn\npg_num integer Number of placement groups.\npg_num_min integer Minimal number of placement groups.\nsize integer Number of replicas per object\ntarget_size string The estimated target size of the pool for the PG autoscaler.\ntarget_size_ratio number The estimated target ratio of the pool for the PG autoscaler." + }, + { + "id": "DELETE /nodes/{node}/ceph/pool/{name}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/pool/{name}", + "section": "nodes", + "summary": "destroypool", + "description": "Destroy pool", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the pool. It must be unique." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "If true, destroys pool even if in use", + "default": 0 + }, + { + "name": "remove_ecprofile", + "type": "boolean", + "required": false, + "description": "Remove the erasure code profile. Defaults to true, if applicable.", + "default": 1 + }, + { + "name": "remove_storages", + "type": "boolean", + "required": false, + "description": "Remove all pveceph-managed storages configured for this pool", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/ceph/pool/{name}\nnodes\ndestroypool\nDestroy pool\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\nforce boolean If true, destroys pool even if in use\nremove_ecprofile boolean Remove the erasure code profile. Defaults to true, if applicable.\nremove_storages boolean Remove all pveceph-managed storages configured for this pool" + }, + { + "id": "GET /nodes/{node}/ceph/pool/{name}", + "method": "GET", + "path": "/nodes/{node}/ceph/pool/{name}", + "section": "nodes", + "summary": "poolindex", + "description": "Pool index.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the pool." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/pool/{name}\nnodes\npoolindex\nPool index.\nname string The name of the pool.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/ceph/pool/{name}", + "method": "PUT", + "path": "/nodes/{node}/ceph/pool/{name}", + "section": "nodes", + "summary": "setpool", + "description": "Change POOL settings", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the pool. It must be unique." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "application", + "type": "string", + "required": false, + "description": "The application of the pool.", + "enum": [ + "rbd", + "cephfs", + "rgw" + ] + }, + { + "name": "crush_rule", + "type": "string", + "required": false, + "description": "The rule to use for mapping object placement in the cluster." + }, + { + "name": "min_size", + "type": "integer", + "required": false, + "description": "Minimum number of replicas per object", + "minimum": 1, + "maximum": 7 + }, + { + "name": "pg_autoscale_mode", + "type": "string", + "required": false, + "description": "The automatic PG scaling mode of the pool.", + "enum": [ + "on", + "off", + "warn" + ] + }, + { + "name": "pg_num", + "type": "integer", + "required": false, + "description": "Number of placement groups.", + "minimum": 1, + "maximum": 32768 + }, + { + "name": "pg_num_min", + "type": "integer", + "required": false, + "description": "Minimal number of placement groups.", + "maximum": 32768 + }, + { + "name": "size", + "type": "integer", + "required": false, + "description": "Number of replicas per object", + "minimum": 1, + "maximum": 7 + }, + { + "name": "target_size", + "type": "string", + "required": false, + "description": "The estimated target size of the pool for the PG autoscaler." + }, + { + "name": "target_size_ratio", + "type": "number", + "required": false, + "description": "The estimated target ratio of the pool for the PG autoscaler." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/ceph/pool/{name}\nnodes\nsetpool\nChange POOL settings\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\napplication string The application of the pool. rbd cephfs rgw\ncrush_rule string The rule to use for mapping object placement in the cluster.\nmin_size integer Minimum number of replicas per object\npg_autoscale_mode string The automatic PG scaling mode of the pool. on off warn\npg_num integer Number of placement groups.\npg_num_min integer Minimal number of placement groups.\nsize integer Number of replicas per object\ntarget_size string The estimated target size of the pool for the PG autoscaler.\ntarget_size_ratio number The estimated target ratio of the pool for the PG autoscaler." + }, + { + "id": "GET /nodes/{node}/ceph/pool/{name}/status", + "method": "GET", + "path": "/nodes/{node}/ceph/pool/{name}/status", + "section": "nodes", + "summary": "getpool", + "description": "Show the current pool status.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The name of the pool. It must be unique." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "verbose", + "type": "boolean", + "required": false, + "description": "If enabled, will display additional data(eg. statistics).", + "default": 0 + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/pool/{name}/status\nnodes\ngetpool\nShow the current pool status.\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\nverbose boolean If enabled, will display additional data(eg. statistics)." + }, + { + "id": "POST /nodes/{node}/ceph/restart", + "method": "POST", + "path": "/nodes/{node}/ceph/restart", + "section": "nodes", + "summary": "restart", + "description": "Restart ceph services.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "service", + "type": "string", + "required": false, + "description": "Ceph service name.", + "default": "ceph.target" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/restart\nnodes\nrestart\nRestart ceph services.\nnode string The cluster node name.\nservice string Ceph service name." + }, + { + "id": "GET /nodes/{node}/ceph/rules", + "method": "GET", + "path": "/nodes/{node}/ceph/rules", + "section": "nodes", + "summary": "rules", + "description": "List ceph rules.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "name": { + "description": "Name of the CRUSH rule.", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/rules\nnodes\nrules\nList ceph rules.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/start", + "method": "POST", + "path": "/nodes/{node}/ceph/start", + "section": "nodes", + "summary": "start", + "description": "Start ceph services.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "service", + "type": "string", + "required": false, + "description": "Ceph service name.", + "default": "ceph.target" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/start\nnodes\nstart\nStart ceph services.\nnode string The cluster node name.\nservice string Ceph service name." + }, + { + "id": "GET /nodes/{node}/ceph/status", + "method": "GET", + "path": "/nodes/{node}/ceph/status", + "section": "nodes", + "summary": "status", + "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.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/ceph/status\nnodes\nstatus\nGet 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.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/stop", + "method": "POST", + "path": "/nodes/{node}/ceph/stop", + "section": "nodes", + "summary": "stop", + "description": "Stop ceph services.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "service", + "type": "string", + "required": false, + "description": "Ceph service name.", + "default": "ceph.target" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/ceph/stop\nnodes\nstop\nStop ceph services.\nnode string The cluster node name.\nservice string Ceph service name." + }, + { + "id": "GET /nodes/{node}/certificates", + "method": "GET", + "path": "/nodes/{node}/certificates", + "section": "nodes", + "summary": "index", + "description": "Node index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/certificates\nnodes\nindex\nNode index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/certificates/acme", + "method": "GET", + "path": "/nodes/{node}/certificates/acme", + "section": "nodes", + "summary": "index", + "description": "ACME index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/certificates/acme\nnodes\nindex\nACME index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/certificates/acme/certificate", + "method": "DELETE", + "path": "/nodes/{node}/certificates/acme/certificate", + "section": "nodes", + "summary": "revoke_certificate", + "description": "Revoke existing certificate from CA.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/certificates/acme/certificate\nnodes\nrevoke_certificate\nRevoke existing certificate from CA.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/certificates/acme/certificate", + "method": "POST", + "path": "/nodes/{node}/certificates/acme/certificate", + "section": "nodes", + "summary": "new_certificate", + "description": "Order a new certificate from ACME-compatible CA.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Overwrite existing custom certificate.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/certificates/acme/certificate\nnodes\nnew_certificate\nOrder a new certificate from ACME-compatible CA.\nnode string The cluster node name.\nforce boolean Overwrite existing custom certificate." + }, + { + "id": "PUT /nodes/{node}/certificates/acme/certificate", + "method": "PUT", + "path": "/nodes/{node}/certificates/acme/certificate", + "section": "nodes", + "summary": "renew_certificate", + "description": "Renew existing certificate from CA.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Force renewal even if expiry is more than 30 days away.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/certificates/acme/certificate\nnodes\nrenew_certificate\nRenew existing certificate from CA.\nnode string The cluster node name.\nforce boolean Force renewal even if expiry is more than 30 days away." + }, + { + "id": "DELETE /nodes/{node}/certificates/custom", + "method": "DELETE", + "path": "/nodes/{node}/certificates/custom", + "section": "nodes", + "summary": "remove_custom_cert", + "description": "DELETE custom certificate chain and key.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "restart", + "type": "boolean", + "required": false, + "description": "Restart pveproxy.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/certificates/custom\nnodes\nremove_custom_cert\nDELETE custom certificate chain and key.\nnode string The cluster node name.\nrestart boolean Restart pveproxy." + }, + { + "id": "POST /nodes/{node}/certificates/custom", + "method": "POST", + "path": "/nodes/{node}/certificates/custom", + "section": "nodes", + "summary": "upload_custom_cert", + "description": "Upload or update custom certificate chain and key.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "certificates", + "type": "string", + "required": true, + "description": "PEM encoded certificate (chain).", + "format": "pem-certificate-chain" + }, + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Overwrite existing custom or ACME certificate files.", + "default": 0 + }, + { + "name": "key", + "type": "string", + "required": false, + "description": "PEM encoded private key.", + "format": "pem-string" + }, + { + "name": "restart", + "type": "boolean", + "required": false, + "description": "Restart pveproxy.", + "default": 0 + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/certificates/custom\nnodes\nupload_custom_cert\nUpload or update custom certificate chain and key.\nnode string The cluster node name.\ncertificates string PEM encoded certificate (chain).\nforce boolean Overwrite existing custom or ACME certificate files.\nkey string PEM encoded private key.\nrestart boolean Restart pveproxy." + }, + { + "id": "GET /nodes/{node}/certificates/info", + "method": "GET", + "path": "/nodes/{node}/certificates/info", + "section": "nodes", + "summary": "info", + "description": "Get information about node's certificates.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/certificates/info\nnodes\ninfo\nGet information about node's certificates.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/config", + "method": "GET", + "path": "/nodes/{node}/config", + "section": "nodes", + "summary": "get_config", + "description": "Get node configuration options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "property", + "type": "string", + "required": false, + "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" + ], + "default": "all" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/config\nnodes\nget_config\nGet node configuration options.\nnode string The cluster node name.\nproperty string Return only a specific property from the node configuration. acme acmedomain0 acmedomain1 acmedomain2 acmedomain3 acmedomain4 acmedomain5 ballooning-target description location startall-onboot-delay wakeonlan" + }, + { + "id": "PUT /nodes/{node}/config", + "method": "PUT", + "path": "/nodes/{node}/config", + "section": "nodes", + "summary": "set_options", + "description": "Set node configuration options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "acme", + "type": "string", + "required": false, + "description": "Node specific ACME settings." + }, + { + "name": "acmedomain[n]", + "type": "string", + "required": false, + "description": "ACME domain and validation plugin" + }, + { + "name": "ballooning-target", + "type": "integer", + "required": false, + "description": "RAM usage target for ballooning (in percent of total memory)", + "default": 80, + "minimum": 0, + "maximum": 100 + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications." + }, + { + "name": "location", + "type": "string", + "required": false, + "description": "The location of the node. Overrides the default from the datacenter config." + }, + { + "name": "startall-onboot-delay", + "type": "integer", + "required": false, + "description": "Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.", + "default": 0, + "minimum": 0, + "maximum": 300 + }, + { + "name": "wakeonlan", + "type": "string", + "required": false, + "description": "Node specific wake on LAN settings." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/config\nnodes\nset_options\nSet node configuration options.\nnode string The cluster node name.\nacme string Node specific ACME settings.\nacmedomain[n] string ACME domain and validation plugin\nballooning-target integer RAM usage target for ballooning (in percent of total memory)\ndelete string A list of settings you want to delete.\ndescription string Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nlocation string The location of the node. Overrides the default from the datacenter config.\nstartall-onboot-delay integer Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.\nwakeonlan string Node specific wake on LAN settings." + }, + { + "id": "GET /nodes/{node}/disks", + "method": "GET", + "path": "/nodes/{node}/disks", + "section": "nodes", + "summary": "index", + "description": "Node index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks\nnodes\nindex\nNode index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/disks/directory", + "method": "GET", + "path": "/nodes/{node}/disks/directory", + "section": "nodes", + "summary": "index", + "description": "PVE Managed Directory storages.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks/directory\nnodes\nindex\nPVE Managed Directory storages.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/directory", + "method": "POST", + "path": "/nodes/{node}/disks/directory", + "section": "nodes", + "summary": "create", + "description": "Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "device", + "type": "string", + "required": true, + "description": "The block device you want to create the filesystem on." + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "add_storage", + "type": "boolean", + "required": false, + "description": "Configure storage using the directory.", + "default": 0 + }, + { + "name": "filesystem", + "type": "string", + "required": false, + "description": "The desired filesystem.", + "enum": [ + "ext4", + "xfs" + ], + "default": "ext4" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/disks/directory\nnodes\ncreate\nCreate a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.\nnode string The cluster node name.\ndevice string The block device you want to create the filesystem on.\nname string The storage identifier.\nadd_storage boolean Configure storage using the directory.\nfilesystem string The desired filesystem. ext4 xfs" + }, + { + "id": "DELETE /nodes/{node}/disks/directory/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/directory/{name}", + "section": "nodes", + "summary": "delete", + "description": "Unmounts the storage and removes the mount unit.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "cleanup-config", + "type": "boolean", + "required": false, + "description": "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "default": 0 + }, + { + "name": "cleanup-disks", + "type": "boolean", + "required": false, + "description": "Also wipe disk so it can be repurposed afterwards.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/disks/directory/{name}\nnodes\ndelete\nUnmounts the storage and removes the mount unit.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disk so it can be repurposed afterwards." + }, + { + "id": "POST /nodes/{node}/disks/initgpt", + "method": "POST", + "path": "/nodes/{node}/disks/initgpt", + "section": "nodes", + "summary": "initgpt", + "description": "Initialize Disk with GPT", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "disk", + "type": "string", + "required": true, + "description": "Block device name" + }, + { + "name": "uuid", + "type": "string", + "required": false, + "description": "UUID for the GPT table" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/disks/initgpt\nnodes\ninitgpt\nInitialize Disk with GPT\nnode string The cluster node name.\ndisk string Block device name\nuuid string UUID for the GPT table" + }, + { + "id": "GET /nodes/{node}/disks/list", + "method": "GET", + "path": "/nodes/{node}/disks/list", + "section": "nodes", + "summary": "list", + "description": "List local disks.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "include-partitions", + "type": "boolean", + "required": false, + "description": "Also include partitions.", + "default": 0 + }, + { + "name": "skipsmart", + "type": "boolean", + "required": false, + "description": "Skip smart checks.", + "default": 0 + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list specific types of disks.", + "enum": [ + "unused", + "journal_disks" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks/list\nnodes\nlist\nList local disks.\nnode string The cluster node name.\ninclude-partitions boolean Also include partitions.\nskipsmart boolean Skip smart checks.\ntype string Only list specific types of disks. unused journal_disks" + }, + { + "id": "GET /nodes/{node}/disks/lvm", + "method": "GET", + "path": "/nodes/{node}/disks/lvm", + "section": "nodes", + "summary": "index", + "description": "List LVM Volume Groups", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks/lvm\nnodes\nindex\nList LVM Volume Groups\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/lvm", + "method": "POST", + "path": "/nodes/{node}/disks/lvm", + "section": "nodes", + "summary": "create", + "description": "Create an LVM Volume Group", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "device", + "type": "string", + "required": true, + "description": "The block device you want to create the volume group on" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "add_storage", + "type": "boolean", + "required": false, + "description": "Configure storage using the Volume Group", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/disks/lvm\nnodes\ncreate\nCreate an LVM Volume Group\nnode string The cluster node name.\ndevice string The block device you want to create the volume group on\nname string The storage identifier.\nadd_storage boolean Configure storage using the Volume Group" + }, + { + "id": "DELETE /nodes/{node}/disks/lvm/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/lvm/{name}", + "section": "nodes", + "summary": "delete", + "description": "Remove an LVM Volume Group.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "cleanup-config", + "type": "boolean", + "required": false, + "description": "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "default": 0 + }, + { + "name": "cleanup-disks", + "type": "boolean", + "required": false, + "description": "Also wipe disks so they can be repurposed afterwards.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/disks/lvm/{name}\nnodes\ndelete\nRemove an LVM Volume Group.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards." + }, + { + "id": "GET /nodes/{node}/disks/lvmthin", + "method": "GET", + "path": "/nodes/{node}/disks/lvmthin", + "section": "nodes", + "summary": "index", + "description": "List LVM thinpools", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks/lvmthin\nnodes\nindex\nList LVM thinpools\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/lvmthin", + "method": "POST", + "path": "/nodes/{node}/disks/lvmthin", + "section": "nodes", + "summary": "create", + "description": "Create an LVM thinpool", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "device", + "type": "string", + "required": true, + "description": "The block device you want to create the thinpool on." + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "add_storage", + "type": "boolean", + "required": false, + "description": "Configure storage using the thinpool.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/disks/lvmthin\nnodes\ncreate\nCreate an LVM thinpool\nnode string The cluster node name.\ndevice string The block device you want to create the thinpool on.\nname string The storage identifier.\nadd_storage boolean Configure storage using the thinpool." + }, + { + "id": "DELETE /nodes/{node}/disks/lvmthin/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/lvmthin/{name}", + "section": "nodes", + "summary": "delete", + "description": "Remove an LVM thin pool.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "volume-group", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "cleanup-config", + "type": "boolean", + "required": false, + "description": "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "default": 0 + }, + { + "name": "cleanup-disks", + "type": "boolean", + "required": false, + "description": "Also wipe disks so they can be repurposed afterwards.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/disks/lvmthin/{name}\nnodes\ndelete\nRemove an LVM thin pool.\nname string The storage identifier.\nnode string The cluster node name.\nvolume-group string The storage identifier.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards." + }, + { + "id": "GET /nodes/{node}/disks/smart", + "method": "GET", + "path": "/nodes/{node}/disks/smart", + "section": "nodes", + "summary": "smart", + "description": "Get SMART Health of a disk.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "disk", + "type": "string", + "required": true, + "description": "Block device name" + }, + { + "name": "healthonly", + "type": "boolean", + "required": false, + "description": "If true returns only the health status" + } + ], + "returns": { + "properties": { + "attributes": { + "optional": 1, + "type": "array" + }, + "health": { + "type": "string" + }, + "text": { + "optional": 1, + "type": "string" + }, + "type": { + "optional": 1, + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks/smart\nnodes\nsmart\nGet SMART Health of a disk.\nnode string The cluster node name.\ndisk string Block device name\nhealthonly boolean If true returns only the health status" + }, + { + "id": "PUT /nodes/{node}/disks/wipedisk", + "method": "PUT", + "path": "/nodes/{node}/disks/wipedisk", + "section": "nodes", + "summary": "wipe_disk", + "description": "Wipe a disk or partition.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "disk", + "type": "string", + "required": true, + "description": "Block device name" + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/disks/wipedisk\nnodes\nwipe_disk\nWipe a disk or partition.\nnode string The cluster node name.\ndisk string Block device name" + }, + { + "id": "GET /nodes/{node}/disks/zfs", + "method": "GET", + "path": "/nodes/{node}/disks/zfs", + "section": "nodes", + "summary": "index", + "description": "List Zpools.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks/zfs\nnodes\nindex\nList Zpools.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/zfs", + "method": "POST", + "path": "/nodes/{node}/disks/zfs", + "section": "nodes", + "summary": "create", + "description": "Create a ZFS pool.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "devices", + "type": "string", + "required": true, + "description": "The block devices you want to create the zpool on.", + "format": "string-list" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "raidlevel", + "type": "string", + "required": true, + "description": "The RAID level to use.", + "enum": [ + "single", + "mirror", + "raid10", + "raidz", + "raidz2", + "raidz3", + "draid", + "draid2", + "draid3" + ] + }, + { + "name": "add_storage", + "type": "boolean", + "required": false, + "description": "Configure storage using the zpool.", + "default": 0 + }, + { + "name": "ashift", + "type": "integer", + "required": false, + "description": "Pool sector size exponent.", + "default": 12, + "minimum": 9, + "maximum": 16 + }, + { + "name": "compression", + "type": "string", + "required": false, + "description": "The compression algorithm to use.", + "enum": [ + "on", + "off", + "gzip", + "lz4", + "lzjb", + "zle", + "zstd" + ], + "default": "on" + }, + { + "name": "draid-config", + "type": "string", + "required": false + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/disks/zfs\nnodes\ncreate\nCreate a ZFS pool.\nnode string The cluster node name.\ndevices string The block devices you want to create the zpool on.\nname string The storage identifier.\nraidlevel string The RAID level to use. single mirror raid10 raidz raidz2 raidz3 draid draid2 draid3\nadd_storage boolean Configure storage using the zpool.\nashift integer Pool sector size exponent.\ncompression string The compression algorithm to use. on off gzip lz4 lzjb zle zstd\ndraid-config string" + }, + { + "id": "DELETE /nodes/{node}/disks/zfs/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/zfs/{name}", + "section": "nodes", + "summary": "delete", + "description": "Destroy a ZFS pool.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "cleanup-config", + "type": "boolean", + "required": false, + "description": "Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).", + "default": 0 + }, + { + "name": "cleanup-disks", + "type": "boolean", + "required": false, + "description": "Also wipe disks so they can be repurposed afterwards.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/disks/zfs/{name}\nnodes\ndelete\nDestroy a ZFS pool.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards." + }, + { + "id": "GET /nodes/{node}/disks/zfs/{name}", + "method": "GET", + "path": "/nodes/{node}/disks/zfs/{name}", + "section": "nodes", + "summary": "detail", + "description": "Get details about a zpool.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/disks/zfs/{name}\nnodes\ndetail\nGet details about a zpool.\nname string The storage identifier.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/dns", + "method": "GET", + "path": "/nodes/{node}/dns", + "section": "nodes", + "summary": "dns", + "description": "Read DNS settings.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/dns\nnodes\ndns\nRead DNS settings.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/dns", + "method": "PUT", + "path": "/nodes/{node}/dns", + "section": "nodes", + "summary": "update_dns", + "description": "Write DNS settings.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "search", + "type": "string", + "required": true, + "description": "Search domain for host-name lookup." + }, + { + "name": "dns1", + "type": "string", + "required": false, + "description": "First name server IP address.", + "format": "ip" + }, + { + "name": "dns2", + "type": "string", + "required": false, + "description": "Second name server IP address.", + "format": "ip" + }, + { + "name": "dns3", + "type": "string", + "required": false, + "description": "Third name server IP address.", + "format": "ip" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/dns\nnodes\nupdate_dns\nWrite DNS settings.\nnode string The cluster node name.\nsearch string Search domain for host-name lookup.\ndns1 string First name server IP address.\ndns2 string Second name server IP address.\ndns3 string Third name server IP address." + }, + { + "id": "POST /nodes/{node}/execute", + "method": "POST", + "path": "/nodes/{node}/execute", + "section": "nodes", + "summary": "execute", + "description": "Execute multiple commands in order, root only.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "commands", + "type": "string", + "required": true, + "description": "JSON encoded array of commands.", + "format": "pve-command-batch" + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/execute\nnodes\nexecute\nExecute multiple commands in order, root only.\nnode string The cluster node name.\ncommands string JSON encoded array of commands." + }, + { + "id": "GET /nodes/{node}/firewall", + "method": "GET", + "path": "/nodes/{node}/firewall", + "section": "nodes", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/firewall/log", + "method": "GET", + "path": "/nodes/{node}/firewall/log", + "section": "nodes", + "summary": "log", + "description": "Read firewall log", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "limit", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "since", + "type": "integer", + "required": false, + "description": "Display log since this UNIX epoch.", + "minimum": 0 + }, + { + "name": "start", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "until", + "type": "integer", + "required": false, + "description": "Display log until this UNIX epoch.", + "minimum": 0 + } + ], + "returns": { + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch." + }, + { + "id": "GET /nodes/{node}/firewall/options", + "method": "GET", + "path": "/nodes/{node}/firewall/options", + "section": "nodes", + "summary": "get_options", + "description": "Get host firewall options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/firewall/options\nnodes\nget_options\nGet host firewall options.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/firewall/options", + "method": "PUT", + "path": "/nodes/{node}/firewall/options", + "section": "nodes", + "summary": "set_options", + "description": "Set Firewall options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "enable", + "type": "boolean", + "required": false, + "description": "Enable host firewall rules.", + "default": 1 + }, + { + "name": "log_level_forward", + "type": "string", + "required": false, + "description": "Log level for forwarded traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "log_level_in", + "type": "string", + "required": false, + "description": "Log level for incoming traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "log_level_out", + "type": "string", + "required": false, + "description": "Log level for outgoing traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "log_nf_conntrack", + "type": "boolean", + "required": false, + "description": "Enable logging of conntrack information.", + "default": 0 + }, + { + "name": "ndp", + "type": "boolean", + "required": false, + "description": "Enable NDP (Neighbor Discovery Protocol).", + "default": 1 + }, + { + "name": "nf_conntrack_allow_invalid", + "type": "boolean", + "required": false, + "description": "Allow invalid packets on connection tracking.", + "default": 0 + }, + { + "name": "nf_conntrack_helpers", + "type": "string", + "required": false, + "description": "Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp", + "default": "", + "format": "pve-fw-conntrack-helper" + }, + { + "name": "nf_conntrack_max", + "type": "integer", + "required": false, + "description": "Maximum number of tracked connections.", + "default": 262144, + "minimum": 32768 + }, + { + "name": "nf_conntrack_tcp_timeout_established", + "type": "integer", + "required": false, + "description": "Conntrack established timeout.", + "default": 432000, + "minimum": 7875 + }, + { + "name": "nf_conntrack_tcp_timeout_syn_recv", + "type": "integer", + "required": false, + "description": "Conntrack syn recv timeout.", + "default": 60, + "minimum": 30, + "maximum": 60 + }, + { + "name": "nftables", + "type": "boolean", + "required": false, + "description": "Enable nftables based firewall (tech preview)", + "default": 0 + }, + { + "name": "nosmurfs", + "type": "boolean", + "required": false, + "description": "Enable SMURFS filter." + }, + { + "name": "protection_synflood", + "type": "boolean", + "required": false, + "description": "Enable synflood protection", + "default": 0 + }, + { + "name": "protection_synflood_burst", + "type": "integer", + "required": false, + "description": "Synflood protection rate burst by ip src.", + "default": 1000 + }, + { + "name": "protection_synflood_rate", + "type": "integer", + "required": false, + "description": "Synflood protection rate syn/sec by ip src.", + "default": 200 + }, + { + "name": "smurf_log_level", + "type": "string", + "required": false, + "description": "Log level for SMURFS filter.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "tcp_flags_log_level", + "type": "string", + "required": false, + "description": "Log level for illegal tcp flags filter.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "tcpflags", + "type": "boolean", + "required": false, + "description": "Filter illegal combinations of TCP flags.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable host firewall rules.\nlog_level_forward string Log level for forwarded traffic. emerg alert crit err warning notice info debug nolog\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nlog_nf_conntrack boolean Enable logging of conntrack information.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\nnf_conntrack_allow_invalid boolean Allow invalid packets on connection tracking.\nnf_conntrack_helpers string Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp\nnf_conntrack_max integer Maximum number of tracked connections.\nnf_conntrack_tcp_timeout_established integer Conntrack established timeout.\nnf_conntrack_tcp_timeout_syn_recv integer Conntrack syn recv timeout.\nnftables boolean Enable nftables based firewall (tech preview)\nnosmurfs boolean Enable SMURFS filter.\nprotection_synflood boolean Enable synflood protection\nprotection_synflood_burst integer Synflood protection rate burst by ip src.\nprotection_synflood_rate integer Synflood protection rate syn/sec by ip src.\nsmurf_log_level string Log level for SMURFS filter. emerg alert crit err warning notice info debug nolog\ntcp_flags_log_level string Log level for illegal tcp flags filter. emerg alert crit err warning notice info debug nolog\ntcpflags boolean Filter illegal combinations of TCP flags." + }, + { + "id": "GET /nodes/{node}/firewall/rules", + "method": "GET", + "path": "/nodes/{node}/firewall/rules", + "section": "nodes", + "summary": "get_rules", + "description": "List rules.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/firewall/rules", + "method": "POST", + "path": "/nodes/{node}/firewall/rules", + "section": "nodes", + "summary": "create_rule", + "description": "Create new rule.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /nodes/{node}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/nodes/{node}/firewall/rules/{pos}", + "section": "nodes", + "summary": "delete_rule", + "description": "Delete rule.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /nodes/{node}/firewall/rules/{pos}", + "method": "GET", + "path": "/nodes/{node}/firewall/rules/{pos}", + "section": "nodes", + "summary": "get_rule", + "description": "Get single rule data.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\npos integer Update rule at position ." + }, + { + "id": "PUT /nodes/{node}/firewall/rules/{pos}", + "method": "PUT", + "path": "/nodes/{node}/firewall/rules/{pos}", + "section": "nodes", + "summary": "update_rule", + "description": "Modify rule data.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "moveto", + "type": "integer", + "required": false, + "description": "Move rule to new position . Other arguments are ignored.", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "GET /nodes/{node}/hardware", + "method": "GET", + "path": "/nodes/{node}/hardware", + "section": "nodes", + "summary": "index", + "description": "Index of hardware types", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{type}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/hardware\nnodes\nindex\nIndex of hardware types\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/hardware/pci", + "method": "GET", + "path": "/nodes/{node}/hardware/pci", + "section": "nodes", + "summary": "pci_scan", + "description": "List local PCI devices.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "pci-class-blacklist", + "type": "string", + "required": false, + "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).", + "default": "05;06;0b", + "format": "string-list" + }, + { + "name": "verbose", + "type": "boolean", + "required": false, + "description": "If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.", + "default": 1 + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/hardware/pci\nnodes\npci_scan\nList local PCI devices.\nnode string The cluster node name.\npci-class-blacklist string A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).\nverbose boolean If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned." + }, + { + "id": "GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "method": "GET", + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "section": "nodes", + "summary": "pci_index", + "description": "Index of available pci methods", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "pci-id-or-mapping", + "type": "string", + "required": true + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "method": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{method}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/hardware/pci/{pci-id-or-mapping}\nnodes\npci_index\nIndex of available pci methods\nnode string The cluster node name.\npci-id-or-mapping string" + }, + { + "id": "GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "method": "GET", + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "section": "nodes", + "summary": "mdevscan", + "description": "List mediated device types for given PCI device.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "pci-id-or-mapping", + "type": "string", + "required": true, + "description": "The PCI ID or mapping to list the mdev types for." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev\nnodes\nmdevscan\nList mediated device types for given PCI device.\nnode string The cluster node name.\npci-id-or-mapping string The PCI ID or mapping to list the mdev types for." + }, + { + "id": "GET /nodes/{node}/hardware/usb", + "method": "GET", + "path": "/nodes/{node}/hardware/usb", + "section": "nodes", + "summary": "usbscan", + "description": "List local USB devices.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/hardware/usb\nnodes\nusbscan\nList local USB devices.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/hosts", + "method": "GET", + "path": "/nodes/{node}/hosts", + "section": "nodes", + "summary": "get_etc_hosts", + "description": "Get the content of /etc/hosts.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/hosts\nnodes\nget_etc_hosts\nGet the content of /etc/hosts.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/hosts", + "method": "POST", + "path": "/nodes/{node}/hosts", + "section": "nodes", + "summary": "write_etc_hosts", + "description": "Write /etc/hosts.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "data", + "type": "string", + "required": true, + "description": "The target content of /etc/hosts." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/hosts\nnodes\nwrite_etc_hosts\nWrite /etc/hosts.\nnode string The cluster node name.\ndata string The target content of /etc/hosts.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /nodes/{node}/journal", + "method": "GET", + "path": "/nodes/{node}/journal", + "section": "nodes", + "summary": "journal", + "description": "Read Journal", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "endcursor", + "type": "string", + "required": false, + "description": "End before the given Cursor. Conflicts with 'until'" + }, + { + "name": "lastentries", + "type": "integer", + "required": false, + "description": "Limit to the last X lines. Conflicts with a range.", + "minimum": 0 + }, + { + "name": "since", + "type": "integer", + "required": false, + "description": "Display all log since this UNIX epoch. Conflicts with 'startcursor'.", + "minimum": 0 + }, + { + "name": "startcursor", + "type": "string", + "required": false, + "description": "Start after the given Cursor. Conflicts with 'since'" + }, + { + "name": "until", + "type": "integer", + "required": false, + "description": "Display all log until this UNIX epoch. Conflicts with 'endcursor'.", + "minimum": 0 + } + ], + "returns": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/journal\nnodes\njournal\nRead Journal\nnode string The cluster node name.\nendcursor string End before the given Cursor. Conflicts with 'until'\nlastentries integer Limit to the last X lines. Conflicts with a range.\nsince integer Display all log since this UNIX epoch. Conflicts with 'startcursor'.\nstartcursor string Start after the given Cursor. Conflicts with 'since'\nuntil integer Display all log until this UNIX epoch. Conflicts with 'endcursor'." + }, + { + "id": "GET /nodes/{node}/lxc", + "method": "GET", + "path": "/nodes/{node}/lxc", + "section": "nodes", + "summary": "vmlist", + "description": "LXC container index (per node).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Only list CTs where you have VM.Audit permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc\nnodes\nvmlist\nLXC container index (per node).\nnode string The cluster node name.\ncontainer\nct" + }, + { + "id": "POST /nodes/{node}/lxc", + "method": "POST", + "path": "/nodes/{node}/lxc", + "section": "nodes", + "summary": "create_vm", + "description": "Create or restore a container.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "ostemplate", + "type": "string", + "required": true, + "description": "The OS template or backup file." + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "arch", + "type": "string", + "required": false, + "description": "OS architecture type.", + "enum": [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "default": "amd64" + }, + { + "name": "bwlimit", + "type": "number", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "restore limit from datacenter or storage config" + }, + { + "name": "cmode", + "type": "string", + "required": false, + "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" + ], + "default": "tty" + }, + { + "name": "console", + "type": "boolean", + "required": false, + "description": "Attach a console device (/dev/console) to the container.", + "default": 1 + }, + { + "name": "cores", + "type": "integer", + "required": false, + "description": "The number of cores assigned to the container. A container can use all available cores by default.", + "minimum": 1, + "maximum": 8192 + }, + { + "name": "cpulimit", + "type": "number", + "required": false, + "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.", + "default": 0, + "minimum": 0, + "maximum": 8192 + }, + { + "name": "cpuunits", + "type": "integer", + "required": false, + "description": "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "default": "cgroup v1: 1024, cgroup v2: 100", + "minimum": 0, + "maximum": 500000 + }, + { + "name": "debug", + "type": "boolean", + "required": false, + "description": "Try to be more verbose. For now this only enables debug log-level on start.", + "default": 0 + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file." + }, + { + "name": "dev[n]", + "type": "string", + "required": false, + "description": "Device to pass through to the container" + }, + { + "name": "entrypoint", + "type": "string", + "required": false, + "description": "Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.", + "default": "/sbin/init" + }, + { + "name": "env", + "type": "string", + "required": false, + "description": "The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config." + }, + { + "name": "features", + "type": "string", + "required": false, + "description": "Allow containers access to advanced features." + }, + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Allow to overwrite existing container." + }, + { + "name": "ha-managed", + "type": "boolean", + "required": false, + "description": "Add the CT as a HA resource after it was created.", + "default": 0 + }, + { + "name": "hookscript", + "type": "string", + "required": false, + "description": "Script that will be executed during various steps in the containers lifetime.", + "format": "pve-volume-id" + }, + { + "name": "hostname", + "type": "string", + "required": false, + "description": "Set a host name for the container.", + "format": "dns-name" + }, + { + "name": "ignore-unpack-errors", + "type": "boolean", + "required": false, + "description": "Ignore errors when extracting the template." + }, + { + "name": "lock", + "type": "string", + "required": false, + "description": "Lock/unlock the container.", + "enum": [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ] + }, + { + "name": "memory", + "type": "integer", + "required": false, + "description": "Amount of RAM for the container in MB.", + "default": 512, + "minimum": 16 + }, + { + "name": "mp[n]", + "type": "string", + "required": false, + "description": "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume." + }, + { + "name": "nameserver", + "type": "string", + "required": false, + "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" + }, + { + "name": "net[n]", + "type": "string", + "required": false, + "description": "Specifies network interfaces for the container." + }, + { + "name": "onboot", + "type": "boolean", + "required": false, + "description": "Specifies whether a container will be started during system bootup.", + "default": 0 + }, + { + "name": "ostype", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "Sets root password inside container." + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Add the VM to the specified pool.", + "format": "pve-poolid" + }, + { + "name": "protection", + "type": "boolean", + "required": false, + "description": "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "default": 0 + }, + { + "name": "restore", + "type": "boolean", + "required": false, + "description": "Mark this as restore task." + }, + { + "name": "rootfs", + "type": "string", + "required": false, + "description": "Use volume as container root." + }, + { + "name": "searchdomain", + "type": "string", + "required": false, + "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" + }, + { + "name": "ssh-public-keys", + "type": "string", + "required": false, + "description": "Setup public SSH keys (one key per line, OpenSSH format)." + }, + { + "name": "start", + "type": "boolean", + "required": false, + "description": "Start the CT after its creation finished successfully.", + "default": 0 + }, + { + "name": "startup", + "type": "string", + "required": false, + "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" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Default Storage.", + "default": "local", + "format": "pve-storage-id" + }, + { + "name": "swap", + "type": "integer", + "required": false, + "description": "Amount of SWAP for the container in MB.", + "default": 512, + "minimum": 0 + }, + { + "name": "tags", + "type": "string", + "required": false, + "description": "Tags of the Container. This is only meta information.", + "format": "pve-tag-list" + }, + { + "name": "template", + "type": "boolean", + "required": false, + "description": "Enable/disable Template.", + "default": 0 + }, + { + "name": "timezone", + "type": "string", + "required": false, + "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" + }, + { + "name": "tty", + "type": "integer", + "required": false, + "description": "Specify the number of tty available to the container", + "default": 2, + "minimum": 0, + "maximum": 6 + }, + { + "name": "unique", + "type": "boolean", + "required": false, + "description": "Assign a unique random ethernet address." + }, + { + "name": "unprivileged", + "type": "boolean", + "required": false, + "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.)", + "default": 0 + }, + { + "name": "unused[n]", + "type": "string", + "required": false, + "description": "Reference to unused volumes. This is used internally, and should not be modified manually." + } + ], + "returns": { + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc\nnodes\ncreate_vm\nCreate or restore a container.\nnode string The cluster node name.\nostemplate string The OS template or backup file.\nvmid integer The (unique) ID of the VM.\narch string OS architecture type. amd64 i386 arm64 armhf riscv32 riscv64\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ncmode string 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). shell console tty\nconsole boolean Attach a console device (/dev/console) to the container.\ncores integer The number of cores assigned to the container. A container can use all available cores by default.\ncpulimit number 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.\ncpuunits integer CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.\ndebug boolean Try to be more verbose. For now this only enables debug log-level on start.\ndescription string Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.\ndev[n] string Device to pass through to the container\nentrypoint string Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.\nenv string The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.\nfeatures string Allow containers access to advanced features.\nforce boolean Allow to overwrite existing container.\nha-managed boolean Add the CT as a HA resource after it was created.\nhookscript string Script that will be executed during various steps in the containers lifetime.\nhostname string Set a host name for the container.\nignore-unpack-errors boolean Ignore errors when extracting the template.\nlock string Lock/unlock the container. backup create destroyed disk fstrim migrate mounted rollback snapshot snapshot-delete\nmemory integer Amount of RAM for the container in MB.\nmp[n] string Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.\nnameserver string Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nnet[n] string Specifies network interfaces for the container.\nonboot boolean Specifies whether a container will be started during system bootup.\nostype string 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. debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo nixos unmanaged\npassword string Sets root password inside container.\npool string Add the VM to the specified pool.\nprotection boolean Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.\nrestore boolean Mark this as restore task.\nrootfs string Use volume as container root.\nsearchdomain string Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nssh-public-keys string Setup public SSH keys (one key per line, OpenSSH format).\nstart boolean Start the CT after its creation finished successfully.\nstartup string 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.\nstorage string Default Storage.\nswap integer Amount of SWAP for the container in MB.\ntags string Tags of the Container. This is only meta information.\ntemplate boolean Enable/disable Template.\ntimezone string 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\ntty integer Specify the number of tty available to the container\nunique boolean Assign a unique random ethernet address.\nunprivileged boolean 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.)\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\ncontainer\nct" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}", + "section": "nodes", + "summary": "destroy_vm", + "description": "Destroy the container (also delete all uses files).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "destroy-unreferenced-disks", + "type": "boolean", + "required": false, + "description": "If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config." + }, + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Force destroy, even if running.", + "default": 0 + }, + { + "name": "purge", + "type": "boolean", + "required": false, + "description": "Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}\nnodes\ndestroy_vm\nDestroy the container (also delete all uses files).\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndestroy-unreferenced-disks boolean If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.\nforce boolean Force destroy, even if running.\npurge boolean Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}", + "section": "nodes", + "summary": "vmdiridx", + "description": "Directory index", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}\nnodes\nvmdiridx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/clone", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/clone", + "section": "nodes", + "summary": "clone_vm", + "description": "Create a container clone/copy", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "newid", + "type": "integer", + "required": true, + "description": "VMID for the clone.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "bwlimit", + "type": "number", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "clone limit from datacenter or storage config" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the new CT." + }, + { + "name": "full", + "type": "boolean", + "required": false, + "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." + }, + { + "name": "hostname", + "type": "string", + "required": false, + "description": "Set a hostname for the new CT.", + "format": "dns-name" + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Add the new CT to the specified pool.", + "format": "pve-poolid" + }, + { + "name": "snapname", + "type": "string", + "required": false, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Target storage for full clone.", + "format": "pve-storage-id" + }, + { + "name": "target", + "type": "string", + "required": false, + "description": "Target node. Only allowed if the original VM is on shared storage.", + "format": "pve-node" + } + ], + "returns": { + "type": "string" + }, + "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." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/clone\nnodes\nclone_vm\nCreate a container clone/copy\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnewid integer VMID for the clone.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndescription string Description for the new CT.\nfull boolean 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.\nhostname string Set a hostname for the new CT.\npool string Add the new CT to the specified pool.\nsnapname string The name of the snapshot.\nstorage string Target storage for full clone.\ntarget string Target node. Only allowed if the original VM is on shared storage.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/config", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/config", + "section": "nodes", + "summary": "vm_config", + "description": "Get container configuration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "current", + "type": "boolean", + "required": false, + "description": "Get current values (instead of pending values).", + "default": 0 + }, + { + "name": "snapshot", + "type": "string", + "required": false, + "description": "Fetch config values from given snapshot.", + "format": "pve-configid" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/config\nnodes\nvm_config\nGet container configuration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncurrent boolean Get current values (instead of pending values).\nsnapshot string Fetch config values from given snapshot.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/config", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/config", + "section": "nodes", + "summary": "update_vm", + "description": "Set container options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "arch", + "type": "string", + "required": false, + "description": "OS architecture type.", + "enum": [ + "amd64", + "i386", + "arm64", + "armhf", + "riscv32", + "riscv64" + ], + "default": "amd64" + }, + { + "name": "cmode", + "type": "string", + "required": false, + "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" + ], + "default": "tty" + }, + { + "name": "console", + "type": "boolean", + "required": false, + "description": "Attach a console device (/dev/console) to the container.", + "default": 1 + }, + { + "name": "cores", + "type": "integer", + "required": false, + "description": "The number of cores assigned to the container. A container can use all available cores by default.", + "minimum": 1, + "maximum": 8192 + }, + { + "name": "cpulimit", + "type": "number", + "required": false, + "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.", + "default": 0, + "minimum": 0, + "maximum": 8192 + }, + { + "name": "cpuunits", + "type": "integer", + "required": false, + "description": "CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.", + "default": "cgroup v1: 1024, cgroup v2: 100", + "minimum": 0, + "maximum": 500000 + }, + { + "name": "debug", + "type": "boolean", + "required": false, + "description": "Try to be more verbose. For now this only enables debug log-level on start.", + "default": 0 + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file." + }, + { + "name": "dev[n]", + "type": "string", + "required": false, + "description": "Device to pass through to the container" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications." + }, + { + "name": "entrypoint", + "type": "string", + "required": false, + "description": "Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.", + "default": "/sbin/init" + }, + { + "name": "env", + "type": "string", + "required": false, + "description": "The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config." + }, + { + "name": "features", + "type": "string", + "required": false, + "description": "Allow containers access to advanced features." + }, + { + "name": "hookscript", + "type": "string", + "required": false, + "description": "Script that will be executed during various steps in the containers lifetime.", + "format": "pve-volume-id" + }, + { + "name": "hostname", + "type": "string", + "required": false, + "description": "Set a host name for the container.", + "format": "dns-name" + }, + { + "name": "lock", + "type": "string", + "required": false, + "description": "Lock/unlock the container.", + "enum": [ + "backup", + "create", + "destroyed", + "disk", + "fstrim", + "migrate", + "mounted", + "rollback", + "snapshot", + "snapshot-delete" + ] + }, + { + "name": "memory", + "type": "integer", + "required": false, + "description": "Amount of RAM for the container in MB.", + "default": 512, + "minimum": 16 + }, + { + "name": "mp[n]", + "type": "string", + "required": false, + "description": "Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume." + }, + { + "name": "nameserver", + "type": "string", + "required": false, + "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" + }, + { + "name": "net[n]", + "type": "string", + "required": false, + "description": "Specifies network interfaces for the container." + }, + { + "name": "onboot", + "type": "boolean", + "required": false, + "description": "Specifies whether a container will be started during system bootup.", + "default": 0 + }, + { + "name": "ostype", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "protection", + "type": "boolean", + "required": false, + "description": "Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.", + "default": 0 + }, + { + "name": "revert", + "type": "string", + "required": false, + "description": "Revert a pending change.", + "format": "pve-configid-list" + }, + { + "name": "rootfs", + "type": "string", + "required": false, + "description": "Use volume as container root." + }, + { + "name": "searchdomain", + "type": "string", + "required": false, + "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" + }, + { + "name": "startup", + "type": "string", + "required": false, + "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" + }, + { + "name": "swap", + "type": "integer", + "required": false, + "description": "Amount of SWAP for the container in MB.", + "default": 512, + "minimum": 0 + }, + { + "name": "tags", + "type": "string", + "required": false, + "description": "Tags of the Container. This is only meta information.", + "format": "pve-tag-list" + }, + { + "name": "template", + "type": "boolean", + "required": false, + "description": "Enable/disable Template.", + "default": 0 + }, + { + "name": "timezone", + "type": "string", + "required": false, + "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" + }, + { + "name": "tty", + "type": "integer", + "required": false, + "description": "Specify the number of tty available to the container", + "default": 2, + "minimum": 0, + "maximum": 6 + }, + { + "name": "unprivileged", + "type": "boolean", + "required": false, + "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.)", + "default": 0 + }, + { + "name": "unused[n]", + "type": "string", + "required": false, + "description": "Reference to unused volumes. This is used internally, and should not be modified manually." + } + ], + "returns": { + "type": "null" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/config\nnodes\nupdate_vm\nSet container options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\narch string OS architecture type. amd64 i386 arm64 armhf riscv32 riscv64\ncmode string 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). shell console tty\nconsole boolean Attach a console device (/dev/console) to the container.\ncores integer The number of cores assigned to the container. A container can use all available cores by default.\ncpulimit number 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.\ncpuunits integer CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.\ndebug boolean Try to be more verbose. For now this only enables debug log-level on start.\ndelete string A list of settings you want to delete.\ndescription string Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.\ndev[n] string Device to pass through to the container\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nentrypoint string Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.\nenv string The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.\nfeatures string Allow containers access to advanced features.\nhookscript string Script that will be executed during various steps in the containers lifetime.\nhostname string Set a host name for the container.\nlock string Lock/unlock the container. backup create destroyed disk fstrim migrate mounted rollback snapshot snapshot-delete\nmemory integer Amount of RAM for the container in MB.\nmp[n] string Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.\nnameserver string Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nnet[n] string Specifies network interfaces for the container.\nonboot boolean Specifies whether a container will be started during system bootup.\nostype string 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. debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo nixos unmanaged\nprotection boolean Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.\nrevert string Revert a pending change.\nrootfs string Use volume as container root.\nsearchdomain string Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nstartup string 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.\nswap integer Amount of SWAP for the container in MB.\ntags string Tags of the Container. This is only meta information.\ntemplate boolean Enable/disable Template.\ntimezone string 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\ntty integer Specify the number of tty available to the container\nunprivileged boolean 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.)\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/feature", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/feature", + "section": "nodes", + "summary": "vm_feature", + "description": "Check if feature for virtual machine is available.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "feature", + "type": "string", + "required": true, + "description": "Feature to check.", + "enum": [ + "snapshot", + "clone", + "copy" + ] + }, + { + "name": "snapname", + "type": "string", + "required": false, + "description": "The name of the snapshot.", + "format": "pve-configid" + } + ], + "returns": { + "properties": { + "hasFeature": { + "type": "boolean" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/feature\nnodes\nvm_feature\nCheck if feature for virtual machine is available.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfeature string Feature to check. snapshot clone copy\nsnapname string The name of the snapshot.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall", + "section": "nodes", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/aliases", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "get_aliases", + "description": "List aliases", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/aliases\nnodes\nget_aliases\nList aliases\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/aliases", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "create_alias", + "description": "Create IP or Network Alias.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDR" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "comment", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/aliases\nnodes\ncreate_alias\nCreate IP or Network Alias.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "remove_alias", + "description": "Remove IP or Network alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "read_alias", + "description": "Read alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nread_alias\nRead alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "update_alias", + "description": "Update IP or Network alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDR" + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "rename", + "type": "string", + "required": false, + "description": "Rename an existing alias." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "ipset_index", + "description": "List IPSets", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset\nnodes\nipset_index\nList IPSets\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/ipset", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "create_ipset", + "description": "Create new IPSet", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "rename", + "type": "string", + "required": false, + "description": "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/ipset\nnodes\ncreate_ipset\nCreate new IPSet\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "delete_ipset", + "description": "Delete IPSet", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Delete all members of the IPSet, if there are any." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\ndelete_ipset\nDelete IPSet\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce boolean Delete all members of the IPSet, if there are any.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "get_ipset", + "description": "List IPSet content", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\nget_ipset\nList IPSet content\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "create_ip", + "description": "Add IP or Network to IPSet.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "nomatch", + "type": "boolean", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "remove_ip", + "description": "Remove IP or Network from IPSet.", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "read_ip", + "description": "Read IP or Network settings from IPSet.", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "update_ip", + "description": "Update IP or Network settings", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "nomatch", + "type": "boolean", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/log", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/log", + "section": "nodes", + "summary": "log", + "description": "Read firewall log", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "limit", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "since", + "type": "integer", + "required": false, + "description": "Display log since this UNIX epoch.", + "minimum": 0 + }, + { + "name": "start", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "until", + "type": "integer", + "required": false, + "description": "Display log until this UNIX epoch.", + "minimum": 0 + } + ], + "returns": { + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/options", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "section": "nodes", + "summary": "get_options", + "description": "Get VM firewall options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/options\nnodes\nget_options\nGet VM firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/options", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "section": "nodes", + "summary": "set_options", + "description": "Set Firewall options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dhcp", + "type": "boolean", + "required": false, + "description": "Enable DHCP.", + "default": 0 + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "enable", + "type": "boolean", + "required": false, + "description": "Enable/disable firewall rules.", + "default": 0 + }, + { + "name": "ipfilter", + "type": "boolean", + "required": false, + "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." + }, + { + "name": "log_level_in", + "type": "string", + "required": false, + "description": "Log level for incoming traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "log_level_out", + "type": "string", + "required": false, + "description": "Log level for outgoing traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macfilter", + "type": "boolean", + "required": false, + "description": "Enable/disable MAC address filter.", + "default": 1 + }, + { + "name": "ndp", + "type": "boolean", + "required": false, + "description": "Enable NDP (Neighbor Discovery Protocol).", + "default": 1 + }, + { + "name": "policy_in", + "type": "string", + "required": false, + "description": "Input policy.", + "enum": [ + "ACCEPT", + "REJECT", + "DROP" + ] + }, + { + "name": "policy_out", + "type": "string", + "required": false, + "description": "Output policy.", + "enum": [ + "ACCEPT", + "REJECT", + "DROP" + ] + }, + { + "name": "radv", + "type": "boolean", + "required": false, + "description": "Allow sending Router Advertisement." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndelete string A list of settings you want to delete.\ndhcp boolean Enable DHCP.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nipfilter boolean 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.\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nmacfilter boolean Enable/disable MAC address filter.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP\nradv boolean Allow sending Router Advertisement.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/refs", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/refs", + "section": "nodes", + "summary": "refs", + "description": "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list references of specified type.", + "enum": [ + "alias", + "ipset" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/refs\nnodes\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Only list references of specified type. alias ipset\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/rules", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "section": "nodes", + "summary": "get_rules", + "description": "List rules.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/rules", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "section": "nodes", + "summary": "create_rule", + "description": "Create new rule.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "delete_rule", + "description": "Delete rule.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "get_rule", + "description": "Get single rule data.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "update_rule", + "description": "Modify rule data.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "moveto", + "type": "integer", + "required": false, + "description": "Move rule to new position . Other arguments are ignored.", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/interfaces", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/interfaces", + "section": "nodes", + "summary": "ip", + "description": "Get IP addresses of the specified container interface.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/interfaces\nnodes\nip\nGet IP addresses of the specified container interface.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/migrate", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm_precondition", + "description": "Get preconditions for migration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "target", + "type": "string", + "required": false, + "description": "Target node.", + "format": "pve-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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/migrate\nnodes\nmigrate_vm_precondition\nGet preconditions for migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/migrate", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm", + "description": "Migrate the container to another node. Creates a new migration task.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "target", + "type": "string", + "required": true, + "description": "Target node.", + "format": "pve-node" + }, + { + "name": "bwlimit", + "type": "number", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "migrate limit from datacenter or storage config" + }, + { + "name": "online", + "type": "boolean", + "required": false, + "description": "Use online/live migration." + }, + { + "name": "restart", + "type": "boolean", + "required": false, + "description": "Use restart migration" + }, + { + "name": "target-storage", + "type": "string", + "required": false, + "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" + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Timeout in seconds for shutdown for restart migration", + "default": 180 + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/migrate\nnodes\nmigrate_vm\nMigrate the container to another node. Creates a new migration task.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\nonline boolean Use online/live migration.\nrestart boolean Use restart migration\ntarget-storage string 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.\ntimeout integer Timeout in seconds for shutdown for restart migration\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/move_volume", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/move_volume", + "section": "nodes", + "summary": "move_volume", + "description": "Move a rootfs-/mp-volume to a different storage or to a different container.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "volume", + "type": "string", + "required": true, + "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" + ] + }, + { + "name": "bwlimit", + "type": "number", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "clone limit from datacenter or storage config" + }, + { + "name": "delete", + "type": "boolean", + "required": false, + "description": "Delete the original volume after successful copy. By default the original is kept as an unused volume entry.", + "default": 0 + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications." + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Target Storage.", + "format": "pve-storage-id" + }, + { + "name": "target-digest", + "type": "string", + "required": false, + "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." + }, + { + "name": "target-vmid", + "type": "integer", + "required": false, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "target-volume", + "type": "string", + "required": false, + "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" + ] + } + ], + "returns": { + "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." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/move_volume\nnodes\nmove_volume\nMove a rootfs-/mp-volume to a different storage or to a different container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvolume string Volume which will be moved. 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\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndelete boolean Delete the original volume after successful copy. By default the original is kept as an unused volume entry.\ndigest string Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.\nstorage string Target Storage.\ntarget-digest string 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.\ntarget-vmid integer The (unique) ID of the VM.\ntarget-volume string The config key the volume will be moved to. Default is the source volume key. 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\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/mtunnel", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/mtunnel", + "section": "nodes", + "summary": "mtunnel", + "description": "Migration tunnel endpoint - only for internal use by CT migration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "bridges", + "type": "string", + "required": false, + "description": "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format": "pve-bridge-id-list" + }, + { + "name": "storages", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "additionalProperties": 0, + "properties": { + "socket": { + "type": "string" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + } + } + }, + "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." + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/mtunnel\nnodes\nmtunnel\nMigration tunnel endpoint - only for internal use by CT migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nbridges string List of network bridges to check availability. Will be checked again for actually used bridges during migration.\nstorages string List of storages to check permission and availability. Will be checked again for all actually used storages during migration.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "section": "nodes", + "summary": "mtunnelwebsocket", + "description": "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "socket", + "type": "string", + "required": true, + "description": "unix socket to forward to" + }, + { + "name": "ticket", + "type": "string", + "required": true, + "description": "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command" + } + ], + "returns": { + "properties": { + "port": { + "optional": 1, + "type": "string" + }, + "socket": { + "optional": 1, + "type": "string" + } + }, + "type": "object" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/mtunnelwebsocket\nnodes\nmtunnelwebsocket\nMigration tunnel endpoint for websocket upgrade - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsocket string unix socket to forward to\nticket string ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/pending", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/pending", + "section": "nodes", + "summary": "vm_pending", + "description": "Get container configuration, including pending changes.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/pending\nnodes\nvm_pending\nGet container configuration, including pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/remote_migrate", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/remote_migrate", + "section": "nodes", + "summary": "remote_migrate_vm", + "description": "Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "target-bridge", + "type": "string", + "required": true, + "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" + }, + { + "name": "target-endpoint", + "type": "string", + "required": true, + "description": "Remote target endpoint", + "format": "proxmox-remote" + }, + { + "name": "target-storage", + "type": "string", + "required": true, + "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" + }, + { + "name": "bwlimit", + "type": "number", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "migrate limit from datacenter or storage config" + }, + { + "name": "delete", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "online", + "type": "boolean", + "required": false, + "description": "Use online/live migration." + }, + { + "name": "restart", + "type": "boolean", + "required": false, + "description": "Use restart migration" + }, + { + "name": "target-vmid", + "type": "integer", + "required": false, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Timeout in seconds for shutdown for restart migration", + "default": 180 + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/remote_migrate\nnodes\nremote_migrate_vm\nMigrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget-bridge string 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.\ntarget-endpoint string Remote target endpoint\ntarget-storage string 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.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndelete boolean 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.\nonline boolean Use online/live migration.\nrestart boolean Use restart migration\ntarget-vmid integer The (unique) ID of the VM.\ntimeout integer Timeout in seconds for shutdown for restart migration\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/resize", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/resize", + "section": "nodes", + "summary": "resize_vm", + "description": "Resize a container mount point.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "disk", + "type": "string", + "required": true, + "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" + ] + }, + { + "name": "size", + "type": "string", + "required": true, + "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." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/resize\nnodes\nresize_vm\nResize a container mount point.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to resize. 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\nsize string 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.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/rrd", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/rrd", + "section": "nodes", + "summary": "rrd", + "description": "Read VM RRD statistics (returns PNG)", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "ds", + "type": "string", + "required": true, + "description": "The list of datasources you want to display.", + "format": "pve-configid-list" + }, + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/rrd\nnodes\nrrd\nRead VM RRD statistics (returns PNG)\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/rrddata", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/rrddata", + "section": "nodes", + "summary": "rrddata", + "description": "Read VM RRD statistics", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/rrddata\nnodes\nrrddata\nRead VM RRD statistics\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/snapshot", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "section": "nodes", + "summary": "list", + "description": "List all snapshots.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/snapshot\nnodes\nlist\nList all snapshots.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/snapshot", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "section": "nodes", + "summary": "snapshot", + "description": "Snapshot a container.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "A textual description or comment." + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/snapshot\nnodes\nsnapshot\nSnapshot a container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsnapname string The name of the snapshot.\ndescription string A textual description or comment.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "delsnapshot", + "description": "Delete a LXC snapshot.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "For removal from config file, even if removing disk snapshots fails." + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}\nnodes\ndelsnapshot\nDelete a LXC snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nforce boolean For removal from config file, even if removing disk snapshots fails.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "snapshot_cmd_idx", + "description": "snapshot_cmd_idx", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{cmd}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}\nnodes\nsnapshot_cmd_idx\nsnapshot_cmd_idx\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "get_snapshot_config", + "description": "Get snapshot configuration", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config\nnodes\nget_snapshot_config\nGet snapshot configuration\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "update_snapshot_config", + "description": "Update snapshot metadata.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "description", + "type": "string", + "required": false, + "description": "A textual description or comment." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config\nnodes\nupdate_snapshot_config\nUpdate snapshot metadata.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ndescription string A textual description or comment.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "section": "nodes", + "summary": "rollback", + "description": "Rollback LXC state to specified snapshot.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "start", + "type": "boolean", + "required": false, + "description": "Whether the container should get started after rolling back successfully", + "default": 0 + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback\nnodes\nrollback\nRollback LXC state to specified snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nstart boolean Whether the container should get started after rolling back successfully\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/spiceproxy", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/spiceproxy", + "section": "nodes", + "summary": "spiceproxy", + "description": "Returns a SPICE configuration to connect to the CT.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "proxy", + "type": "string", + "required": false, + "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" + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/spiceproxy\nnodes\nspiceproxy\nReturns a SPICE configuration to connect to the CT.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nproxy string 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).\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/status", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/status", + "section": "nodes", + "summary": "vmcmdidx", + "description": "Directory index", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/status\nnodes\nvmcmdidx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/status/current", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/status/current", + "section": "nodes", + "summary": "vm_status", + "description": "Get virtual machine status.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/status/current\nnodes\nvm_status\nGet virtual machine status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/reboot", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/reboot", + "section": "nodes", + "summary": "vm_reboot", + "description": "Reboot the container by shutting it down, and starting it again. Applies pending changes.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Wait maximal timeout seconds for the shutdown.", + "minimum": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/reboot\nnodes\nvm_reboot\nReboot the container by shutting it down, and starting it again. Applies pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeout integer Wait maximal timeout seconds for the shutdown.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/resume", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/resume", + "section": "nodes", + "summary": "vm_resume", + "description": "Resume the container.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/resume\nnodes\nvm_resume\nResume the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/shutdown", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/shutdown", + "section": "nodes", + "summary": "vm_shutdown", + "description": "Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "forceStop", + "type": "boolean", + "required": false, + "description": "Make sure the Container stops.", + "default": 0 + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Wait maximal timeout seconds.", + "default": 60, + "minimum": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/shutdown\nnodes\nvm_shutdown\nShutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforceStop boolean Make sure the Container stops.\ntimeout integer Wait maximal timeout seconds.\ncontainer\nct\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/start", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/start", + "section": "nodes", + "summary": "vm_start", + "description": "Start the container.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "debug", + "type": "boolean", + "required": false, + "description": "If set, enables very verbose debug log-level on start.", + "default": 0 + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/start\nnodes\nvm_start\nStart the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndebug boolean If set, enables very verbose debug log-level on start.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ncontainer\nct\nguest id\nvm id\ncontainer id\nstart\nboot\npower on" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/stop", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/stop", + "section": "nodes", + "summary": "vm_stop", + "description": "Stop the container. This will abruptly stop all processes running in the container.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "overrule-shutdown", + "type": "boolean", + "required": false, + "description": "Try to abort active 'vzshutdown' tasks before stopping.", + "default": 0 + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/stop\nnodes\nvm_stop\nStop the container. This will abruptly stop all processes running in the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\noverrule-shutdown boolean Try to abort active 'vzshutdown' tasks before stopping.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ncontainer\nct\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/suspend", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/suspend", + "section": "nodes", + "summary": "vm_suspend", + "description": "Suspend the container. This is experimental.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/suspend\nnodes\nvm_suspend\nSuspend the container. This is experimental.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/template", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/template", + "section": "nodes", + "summary": "template", + "description": "Create a Template.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description": "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/template\nnodes\ntemplate\nCreate a Template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/termproxy", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/termproxy", + "section": "nodes", + "summary": "termproxy", + "description": "Creates a TCP proxy connection.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "additionalProperties": 0, + "properties": { + "port": { + "type": "integer" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/termproxy\nnodes\ntermproxy\nCreates a TCP proxy connection.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/vncproxy", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/vncproxy", + "section": "nodes", + "summary": "vncproxy", + "description": "Creates a TCP VNC proxy connections.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "height", + "type": "integer", + "required": false, + "description": "sets the height of the console in pixels.", + "minimum": 16, + "maximum": 2160 + }, + { + "name": "websocket", + "type": "boolean", + "required": false, + "description": "use websocket instead of standard VNC." + }, + { + "name": "width", + "type": "integer", + "required": false, + "description": "sets the width of the console in pixels.", + "minimum": 16, + "maximum": 4096 + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/vncproxy\nnodes\nvncproxy\nCreates a TCP VNC proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nheight integer sets the height of the console in pixels.\nwebsocket boolean use websocket instead of standard VNC.\nwidth integer sets the width of the console in pixels.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/vncwebsocket", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "section": "nodes", + "summary": "vncwebsocket", + "description": "Opens a websocket for VNC traffic.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "port", + "type": "integer", + "required": true, + "description": "Port number returned by previous vncproxy call.", + "minimum": 5900, + "maximum": 5999 + }, + { + "name": "vncticket", + "type": "string", + "required": true, + "description": "Ticket from previous call to vncproxy." + } + ], + "returns": { + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nport integer Port number returned by previous vncproxy call.\nvncticket string Ticket from previous call to vncproxy.\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/migrateall", + "method": "POST", + "path": "/nodes/{node}/migrateall", + "section": "nodes", + "summary": "migrateall", + "description": "Migrate all VMs and Containers.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "target", + "type": "string", + "required": true, + "description": "Target node.", + "format": "pve-node" + }, + { + "name": "max-workers", + "type": "integer", + "required": false, + "description": "Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!", + "minimum": 1, + "maximum": 64 + }, + { + "name": "maxworkers", + "type": "integer", + "required": false, + "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.", + "minimum": 1, + "maximum": 64 + }, + { + "name": "vms", + "type": "string", + "required": false, + "description": "Only consider Guests with these IDs.", + "format": "pve-vmid-list" + }, + { + "name": "with-local-disks", + "type": "boolean", + "required": false, + "description": "Enable live storage migration for local disk" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "description": "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/migrateall\nnodes\nmigrateall\nMigrate all VMs and Containers.\nnode string The cluster node name.\ntarget string Target node.\nmax-workers integer Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!\nmaxworkers integer 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.\nvms string Only consider Guests with these IDs.\nwith-local-disks boolean Enable live storage migration for local disk" + }, + { + "id": "GET /nodes/{node}/netstat", + "method": "GET", + "path": "/nodes/{node}/netstat", + "section": "nodes", + "summary": "netstat", + "description": "Read tap/vm network device interface counters", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/netstat\nnodes\nnetstat\nRead tap/vm network device interface counters\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/network", + "method": "DELETE", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "revert_network_changes", + "description": "Revert network configuration changes.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/network\nnodes\nrevert_network_changes\nRevert network configuration changes.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/network", + "method": "GET", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "index", + "description": "List available networks", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "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" + ] + } + ], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/network\nnodes\nindex\nList available networks\nnode string The cluster node name.\ntype string Only list specific interface types. bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet any_bridge any_local_bridge include_sdn" + }, + { + "id": "POST /nodes/{node}/network", + "method": "POST", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "create_network", + "description": "Create network device configuration", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "iface", + "type": "string", + "required": true, + "description": "Network interface name.", + "format": "pve-iface" + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Network interface type", + "enum": [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "fabric", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ] + }, + { + "name": "address", + "type": "string", + "required": false, + "description": "IP address.", + "format": "ipv4" + }, + { + "name": "address6", + "type": "string", + "required": false, + "description": "IP address.", + "format": "ipv6" + }, + { + "name": "autostart", + "type": "boolean", + "required": false, + "description": "Automatically start interface on boot." + }, + { + "name": "bond_mode", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "bond_xmit_hash_policy", + "type": "string", + "required": false, + "description": "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum": [ + "layer2", + "layer2+3", + "layer3+4" + ] + }, + { + "name": "bond-primary", + "type": "string", + "required": false, + "description": "Specify the primary interface for active-backup bond.", + "format": "pve-iface" + }, + { + "name": "bridge_ports", + "type": "string", + "required": false, + "description": "Specify the interfaces you want to add to your bridge.", + "format": "pve-iface-list" + }, + { + "name": "bridge_vids", + "type": "string", + "required": false, + "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" + }, + { + "name": "bridge_vlan_aware", + "type": "boolean", + "required": false, + "description": "Enable bridge vlan support." + }, + { + "name": "cidr", + "type": "string", + "required": false, + "description": "IPv4 CIDR.", + "format": "CIDRv4" + }, + { + "name": "cidr6", + "type": "string", + "required": false, + "description": "IPv6 CIDR.", + "format": "CIDRv6" + }, + { + "name": "comments", + "type": "string", + "required": false, + "description": "Comments" + }, + { + "name": "comments6", + "type": "string", + "required": false, + "description": "Comments" + }, + { + "name": "gateway", + "type": "string", + "required": false, + "description": "Default gateway address.", + "format": "ipv4" + }, + { + "name": "gateway6", + "type": "string", + "required": false, + "description": "Default ipv6 gateway address.", + "format": "ipv6" + }, + { + "name": "mtu", + "type": "integer", + "required": false, + "description": "MTU.", + "minimum": 1280, + "maximum": 65520 + }, + { + "name": "netmask", + "type": "string", + "required": false, + "description": "Network mask.", + "format": "ipv4mask" + }, + { + "name": "netmask6", + "type": "integer", + "required": false, + "description": "Network mask.", + "minimum": 0, + "maximum": 128 + }, + { + "name": "ovs_bonds", + "type": "string", + "required": false, + "description": "Specify the interfaces used by the bonding device.", + "format": "pve-iface-list" + }, + { + "name": "ovs_bridge", + "type": "string", + "required": false, + "description": "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format": "pve-iface" + }, + { + "name": "ovs_options", + "type": "string", + "required": false, + "description": "OVS interface options." + }, + { + "name": "ovs_ports", + "type": "string", + "required": false, + "description": "Specify the interfaces you want to add to your bridge.", + "format": "pve-iface-list" + }, + { + "name": "ovs_tag", + "type": "integer", + "required": false, + "description": "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "minimum": 1, + "maximum": 4094 + }, + { + "name": "slaves", + "type": "string", + "required": false, + "description": "Specify the interfaces used by the bonding device.", + "format": "pve-iface-list" + }, + { + "name": "vlan-id", + "type": "integer", + "required": false, + "description": "vlan-id for a custom named vlan interface (ifupdown2 only).", + "minimum": 1, + "maximum": 4094 + }, + { + "name": "vlan-raw-device", + "type": "string", + "required": false, + "description": "Specify the raw interface for the vlan interface.", + "format": "pve-iface" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/network\nnodes\ncreate_network\nCreate network device configuration\nnode string The cluster node name.\niface string Network interface name.\ntype string Network interface type bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet unknown\naddress string IP address.\naddress6 string IP address.\nautostart boolean Automatically start interface on boot.\nbond_mode string Bonding mode. balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb balance-slb lacp-balance-slb lacp-balance-tcp\nbond_xmit_hash_policy string Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. layer2 layer2+3 layer3+4\nbond-primary string Specify the primary interface for active-backup bond.\nbridge_ports string Specify the interfaces you want to add to your bridge.\nbridge_vids string Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.\nbridge_vlan_aware boolean Enable bridge vlan support.\ncidr string IPv4 CIDR.\ncidr6 string IPv6 CIDR.\ncomments string Comments\ncomments6 string Comments\ngateway string Default gateway address.\ngateway6 string Default ipv6 gateway address.\nmtu integer MTU.\nnetmask string Network mask.\nnetmask6 integer Network mask.\novs_bonds string Specify the interfaces used by the bonding device.\novs_bridge string The OVS bridge associated with a OVS port. This is required when you create an OVS port.\novs_options string OVS interface options.\novs_ports string Specify the interfaces you want to add to your bridge.\novs_tag integer Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)\nslaves string Specify the interfaces used by the bonding device.\nvlan-id integer vlan-id for a custom named vlan interface (ifupdown2 only).\nvlan-raw-device string Specify the raw interface for the vlan interface." + }, + { + "id": "PUT /nodes/{node}/network", + "method": "PUT", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "reload_network_config", + "description": "Reload network configuration", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "regenerate-frr", + "type": "boolean", + "required": false, + "description": "Whether FRR config generation should get skipped or not.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/network\nnodes\nreload_network_config\nReload network configuration\nnode string The cluster node name.\nregenerate-frr boolean Whether FRR config generation should get skipped or not." + }, + { + "id": "DELETE /nodes/{node}/network/{iface}", + "method": "DELETE", + "path": "/nodes/{node}/network/{iface}", + "section": "nodes", + "summary": "delete_network", + "description": "Delete network device configuration", + "pathParameters": [ + { + "name": "iface", + "type": "string", + "required": true, + "description": "Network interface name.", + "format": "pve-iface" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/network/{iface}\nnodes\ndelete_network\nDelete network device configuration\niface string Network interface name.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/network/{iface}", + "method": "GET", + "path": "/nodes/{node}/network/{iface}", + "section": "nodes", + "summary": "network_config", + "description": "Read network device configuration", + "pathParameters": [ + { + "name": "iface", + "type": "string", + "required": true, + "description": "Network interface name.", + "format": "pve-iface" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "properties": { + "method": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/network/{iface}\nnodes\nnetwork_config\nRead network device configuration\niface string Network interface name.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/network/{iface}", + "method": "PUT", + "path": "/nodes/{node}/network/{iface}", + "section": "nodes", + "summary": "update_network", + "description": "Update network device configuration", + "pathParameters": [ + { + "name": "iface", + "type": "string", + "required": true, + "description": "Network interface name.", + "format": "pve-iface" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": true, + "description": "Network interface type", + "enum": [ + "bridge", + "bond", + "eth", + "alias", + "vlan", + "fabric", + "OVSBridge", + "OVSBond", + "OVSPort", + "OVSIntPort", + "vnet", + "unknown" + ] + }, + { + "name": "address", + "type": "string", + "required": false, + "description": "IP address.", + "format": "ipv4" + }, + { + "name": "address6", + "type": "string", + "required": false, + "description": "IP address.", + "format": "ipv6" + }, + { + "name": "autostart", + "type": "boolean", + "required": false, + "description": "Automatically start interface on boot." + }, + { + "name": "bond_mode", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "bond_xmit_hash_policy", + "type": "string", + "required": false, + "description": "Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.", + "enum": [ + "layer2", + "layer2+3", + "layer3+4" + ] + }, + { + "name": "bond-primary", + "type": "string", + "required": false, + "description": "Specify the primary interface for active-backup bond.", + "format": "pve-iface" + }, + { + "name": "bridge_ports", + "type": "string", + "required": false, + "description": "Specify the interfaces you want to add to your bridge.", + "format": "pve-iface-list" + }, + { + "name": "bridge_vids", + "type": "string", + "required": false, + "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" + }, + { + "name": "bridge_vlan_aware", + "type": "boolean", + "required": false, + "description": "Enable bridge vlan support." + }, + { + "name": "cidr", + "type": "string", + "required": false, + "description": "IPv4 CIDR.", + "format": "CIDRv4" + }, + { + "name": "cidr6", + "type": "string", + "required": false, + "description": "IPv6 CIDR.", + "format": "CIDRv6" + }, + { + "name": "comments", + "type": "string", + "required": false, + "description": "Comments" + }, + { + "name": "comments6", + "type": "string", + "required": false, + "description": "Comments" + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "gateway", + "type": "string", + "required": false, + "description": "Default gateway address.", + "format": "ipv4" + }, + { + "name": "gateway6", + "type": "string", + "required": false, + "description": "Default ipv6 gateway address.", + "format": "ipv6" + }, + { + "name": "mtu", + "type": "integer", + "required": false, + "description": "MTU.", + "minimum": 1280, + "maximum": 65520 + }, + { + "name": "netmask", + "type": "string", + "required": false, + "description": "Network mask.", + "format": "ipv4mask" + }, + { + "name": "netmask6", + "type": "integer", + "required": false, + "description": "Network mask.", + "minimum": 0, + "maximum": 128 + }, + { + "name": "ovs_bonds", + "type": "string", + "required": false, + "description": "Specify the interfaces used by the bonding device.", + "format": "pve-iface-list" + }, + { + "name": "ovs_bridge", + "type": "string", + "required": false, + "description": "The OVS bridge associated with a OVS port. This is required when you create an OVS port.", + "format": "pve-iface" + }, + { + "name": "ovs_options", + "type": "string", + "required": false, + "description": "OVS interface options." + }, + { + "name": "ovs_ports", + "type": "string", + "required": false, + "description": "Specify the interfaces you want to add to your bridge.", + "format": "pve-iface-list" + }, + { + "name": "ovs_tag", + "type": "integer", + "required": false, + "description": "Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)", + "minimum": 1, + "maximum": 4094 + }, + { + "name": "slaves", + "type": "string", + "required": false, + "description": "Specify the interfaces used by the bonding device.", + "format": "pve-iface-list" + }, + { + "name": "vlan-id", + "type": "integer", + "required": false, + "description": "vlan-id for a custom named vlan interface (ifupdown2 only).", + "minimum": 1, + "maximum": 4094 + }, + { + "name": "vlan-raw-device", + "type": "string", + "required": false, + "description": "Specify the raw interface for the vlan interface.", + "format": "pve-iface" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/network/{iface}\nnodes\nupdate_network\nUpdate network device configuration\niface string Network interface name.\nnode string The cluster node name.\ntype string Network interface type bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet unknown\naddress string IP address.\naddress6 string IP address.\nautostart boolean Automatically start interface on boot.\nbond_mode string Bonding mode. balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb balance-slb lacp-balance-slb lacp-balance-tcp\nbond_xmit_hash_policy string Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. layer2 layer2+3 layer3+4\nbond-primary string Specify the primary interface for active-backup bond.\nbridge_ports string Specify the interfaces you want to add to your bridge.\nbridge_vids string Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.\nbridge_vlan_aware boolean Enable bridge vlan support.\ncidr string IPv4 CIDR.\ncidr6 string IPv6 CIDR.\ncomments string Comments\ncomments6 string Comments\ndelete string A list of settings you want to delete.\ngateway string Default gateway address.\ngateway6 string Default ipv6 gateway address.\nmtu integer MTU.\nnetmask string Network mask.\nnetmask6 integer Network mask.\novs_bonds string Specify the interfaces used by the bonding device.\novs_bridge string The OVS bridge associated with a OVS port. This is required when you create an OVS port.\novs_options string OVS interface options.\novs_ports string Specify the interfaces you want to add to your bridge.\novs_tag integer Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)\nslaves string Specify the interfaces used by the bonding device.\nvlan-id integer vlan-id for a custom named vlan interface (ifupdown2 only).\nvlan-raw-device string Specify the raw interface for the vlan interface." + }, + { + "id": "GET /nodes/{node}/qemu", + "method": "GET", + "path": "/nodes/{node}/qemu", + "section": "nodes", + "summary": "vmlist", + "description": "Virtual machine index (per node).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "full", + "type": "boolean", + "required": false, + "description": "Determine the full status of active VMs." + } + ], + "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" + }, + "permissions": { + "description": "Only list VMs where you have VM.Audit permissions on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu\nnodes\nvmlist\nVirtual machine index (per node).\nnode string The cluster node name.\nfull boolean Determine the full status of active VMs.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "POST /nodes/{node}/qemu", + "method": "POST", + "path": "/nodes/{node}/qemu", + "section": "nodes", + "summary": "create_vm", + "description": "Create or restore a virtual machine.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "acpi", + "type": "boolean", + "required": false, + "description": "Enable/disable ACPI.", + "default": 1 + }, + { + "name": "affinity", + "type": "string", + "required": false, + "description": "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format": "pve-cpuset" + }, + { + "name": "agent", + "type": "string", + "required": false, + "description": "Enable/disable communication with the QEMU Guest Agent and its properties." + }, + { + "name": "allow-ksm", + "type": "boolean", + "required": false, + "description": "Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).", + "default": 1 + }, + { + "name": "amd-sev", + "type": "string", + "required": false, + "description": "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format": "pve-qemu-sev-fmt" + }, + { + "name": "arch", + "type": "string", + "required": false, + "description": "Virtual processor architecture. Defaults to the host architecture.", + "enum": [ + "x86_64", + "aarch64" + ] + }, + { + "name": "archive", + "type": "string", + "required": false, + "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." + }, + { + "name": "args", + "type": "string", + "required": false, + "description": "Arbitrary arguments passed to kvm." + }, + { + "name": "audio0", + "type": "string", + "required": false, + "description": "Configure a audio device, useful in combination with QXL/Spice." + }, + { + "name": "autostart", + "type": "boolean", + "required": false, + "description": "Automatic restart after crash (currently ignored).", + "default": 0 + }, + { + "name": "balloon", + "type": "integer", + "required": false, + "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 + }, + { + "name": "bios", + "type": "string", + "required": false, + "description": "Select BIOS implementation.", + "enum": [ + "seabios", + "ovmf" + ], + "default": "seabios" + }, + { + "name": "boot", + "type": "string", + "required": false, + "description": "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format": "pve-qm-boot" + }, + { + "name": "bootdisk", + "type": "string", + "required": false, + "description": "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format": "pve-qm-bootdisk" + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "restore limit from datacenter or storage config" + }, + { + "name": "cdrom", + "type": "string", + "required": false, + "description": "This is an alias for option -ide2", + "format": "pve-qm-ide" + }, + { + "name": "cicustom", + "type": "string", + "required": false, + "description": "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format": "pve-qm-cicustom" + }, + { + "name": "cipassword", + "type": "string", + "required": false, + "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." + }, + { + "name": "citype", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "ciupgrade", + "type": "boolean", + "required": false, + "description": "cloud-init: do an automatic package upgrade after the first boot.", + "default": 1 + }, + { + "name": "ciuser", + "type": "string", + "required": false, + "description": "cloud-init: User name to change ssh keys and password for instead of the image's configured default user." + }, + { + "name": "cores", + "type": "integer", + "required": false, + "description": "The number of cores per socket.", + "default": 1, + "minimum": 1 + }, + { + "name": "cpu", + "type": "string", + "required": false, + "description": "Emulated CPU type.", + "format": "pve-vm-cpu-conf" + }, + { + "name": "cpulimit", + "type": "number", + "required": false, + "description": "Limit of CPU usage.", + "default": 0, + "minimum": 0, + "maximum": 128 + }, + { + "name": "cpuunits", + "type": "integer", + "required": false, + "description": "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "default": "cgroup v1: 1024, cgroup v2: 100", + "minimum": 1, + "maximum": 262144 + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file." + }, + { + "name": "efidisk0", + "type": "string", + "required": false, + "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." + }, + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Allow to overwrite existing VM." + }, + { + "name": "freeze", + "type": "boolean", + "required": false, + "description": "Freeze CPU at startup (use 'c' monitor command to start execution)." + }, + { + "name": "ha-managed", + "type": "boolean", + "required": false, + "description": "Add the VM as a HA resource after it was created.", + "default": 0 + }, + { + "name": "hookscript", + "type": "string", + "required": false, + "description": "Script that will be executed during various steps in the vms lifetime.", + "format": "pve-volume-id" + }, + { + "name": "hostpci[n]", + "type": "string", + "required": false, + "description": "Map host PCI devices into guest.", + "format": "pve-qm-hostpci" + }, + { + "name": "hotplug", + "type": "string", + "required": false, + "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.", + "default": "network,disk,usb", + "format": "pve-hotplug-features" + }, + { + "name": "hugepages", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "ide[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "import-working-storage", + "type": "string", + "required": false, + "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" + }, + { + "name": "intel-tdx", + "type": "string", + "required": false, + "description": "Trusted Domain Extension (TDX) features by Intel CPUs", + "format": "pve-qemu-tdx-fmt" + }, + { + "name": "ipconfig[n]", + "type": "string", + "required": false, + "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.", + "format": "pve-qm-ipconfig" + }, + { + "name": "ivshmem", + "type": "string", + "required": false, + "description": "Inter-VM shared memory. Useful for direct communication between VMs, or to the host." + }, + { + "name": "keephugepages", + "type": "boolean", + "required": false, + "description": "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "default": 0 + }, + { + "name": "keyboard", + "type": "string", + "required": false, + "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" + ], + "default": null + }, + { + "name": "kvm", + "type": "boolean", + "required": false, + "description": "Enable/disable KVM hardware virtualization.", + "default": 1 + }, + { + "name": "live-restore", + "type": "boolean", + "required": false, + "description": "Start the VM immediately while importing or restoring in the background." + }, + { + "name": "localtime", + "type": "boolean", + "required": false, + "description": "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS." + }, + { + "name": "lock", + "type": "string", + "required": false, + "description": "Lock/unlock the VM.", + "enum": [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ] + }, + { + "name": "machine", + "type": "string", + "required": false, + "description": "Specify the QEMU machine." + }, + { + "name": "memory", + "type": "string", + "required": false, + "description": "Memory properties." + }, + { + "name": "migrate_downtime", + "type": "number", + "required": false, + "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).", + "default": 0.1, + "minimum": 0 + }, + { + "name": "migrate_speed", + "type": "integer", + "required": false, + "description": "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "default": 0, + "minimum": 0 + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "Set a name for the VM. Only used on the configuration web interface.", + "format": "dns-name" + }, + { + "name": "nameserver", + "type": "string", + "required": false, + "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" + }, + { + "name": "net[n]", + "type": "string", + "required": false, + "description": "Specify network devices." + }, + { + "name": "numa", + "type": "boolean", + "required": false, + "description": "Enable/disable NUMA.", + "default": 0 + }, + { + "name": "numa[n]", + "type": "string", + "required": false, + "description": "NUMA topology." + }, + { + "name": "onboot", + "type": "boolean", + "required": false, + "description": "Specifies whether a VM will be started during system bootup.", + "default": 0 + }, + { + "name": "ostype", + "type": "string", + "required": false, + "description": "Specify guest operating system.", + "enum": [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "default": "other" + }, + { + "name": "parallel[n]", + "type": "string", + "required": false, + "description": "Map host parallel devices (n is 0 to 2)." + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Add the VM to the specified pool.", + "format": "pve-poolid" + }, + { + "name": "protection", + "type": "boolean", + "required": false, + "description": "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "default": 0 + }, + { + "name": "reboot", + "type": "boolean", + "required": false, + "description": "Allow reboot. If set to '0' the VM exit on reboot.", + "default": 1 + }, + { + "name": "rng0", + "type": "string", + "required": false, + "description": "Configure a VirtIO-based Random Number Generator.", + "format": "pve-qm-rng" + }, + { + "name": "sata[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "scsi[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "scsihw", + "type": "string", + "required": false, + "description": "SCSI controller model", + "enum": [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "default": "lsi" + }, + { + "name": "searchdomain", + "type": "string", + "required": false, + "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." + }, + { + "name": "serial[n]", + "type": "string", + "required": false, + "description": "Create a serial device inside the VM (n is 0 to 3)" + }, + { + "name": "shares", + "type": "integer", + "required": false, + "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.", + "default": 1000, + "minimum": 0, + "maximum": 50000 + }, + { + "name": "smbios1", + "type": "string", + "required": false, + "description": "Specify SMBIOS type 1 fields.", + "format": "pve-qm-smbios1" + }, + { + "name": "smp", + "type": "integer", + "required": false, + "description": "The number of CPUs. Please use option -sockets instead.", + "default": 1, + "minimum": 1 + }, + { + "name": "sockets", + "type": "integer", + "required": false, + "description": "The number of CPU sockets.", + "default": 1, + "minimum": 1 + }, + { + "name": "spice_enhancements", + "type": "string", + "required": false, + "description": "Configure additional enhancements for SPICE." + }, + { + "name": "sshkeys", + "type": "string", + "required": false, + "description": "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format": "urlencoded" + }, + { + "name": "start", + "type": "boolean", + "required": false, + "description": "Start VM after it was created successfully.", + "default": 0 + }, + { + "name": "startdate", + "type": "string", + "required": false, + "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'.", + "default": "now" + }, + { + "name": "startup", + "type": "string", + "required": false, + "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" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Default storage.", + "format": "pve-storage-id" + }, + { + "name": "tablet", + "type": "boolean", + "required": false, + "description": "Enable/disable the USB tablet device.", + "default": 1 + }, + { + "name": "tags", + "type": "string", + "required": false, + "description": "Tags of the VM. This is only meta information.", + "format": "pve-tag-list" + }, + { + "name": "tdf", + "type": "boolean", + "required": false, + "description": "Enable/disable time drift fix.", + "default": 0 + }, + { + "name": "template", + "type": "boolean", + "required": false, + "description": "Enable/disable Template.", + "default": 0 + }, + { + "name": "tpmstate0", + "type": "string", + "required": false, + "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." + }, + { + "name": "unique", + "type": "boolean", + "required": false, + "description": "Assign a unique random ethernet address." + }, + { + "name": "unused[n]", + "type": "string", + "required": false, + "description": "Reference to unused volumes. This is used internally, and should not be modified manually." + }, + { + "name": "usb[n]", + "type": "string", + "required": false, + "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)." + }, + { + "name": "vcpus", + "type": "integer", + "required": false, + "description": "Number of hotplugged vcpus.", + "default": 0, + "minimum": 1 + }, + { + "name": "vga", + "type": "string", + "required": false, + "description": "Configure the VGA hardware." + }, + { + "name": "virtio[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "virtiofs[n]", + "type": "string", + "required": false, + "description": "Configuration for sharing a directory between host and guest using Virtio-fs." + }, + { + "name": "vmgenid", + "type": "string", + "required": false, + "description": "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "default": "1 (autogenerated)" + }, + { + "name": "vmstatestorage", + "type": "string", + "required": false, + "description": "Default storage for VM state volumes/files.", + "format": "pve-storage-id" + }, + { + "name": "watchdog", + "type": "string", + "required": false, + "description": "Create a virtual hardware watchdog device.", + "format": "pve-qm-watchdog" + } + ], + "returns": { + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu\nnodes\ncreate_vm\nCreate or restore a virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\narchive string 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.\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\nefidisk0 string 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.\nforce boolean Allow to overwrite existing VM.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nha-managed boolean Add the VM as a HA resource after it was created.\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nimport-working-storage string A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlive-restore boolean Start the VM immediately while importing or restoring in the background.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\npool string Add the VM to the specified pool.\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstart boolean Start VM after it was created successfully.\nstartdate string 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'.\nstartup string 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.\nstorage string Default storage.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunique boolean Assign a unique random ethernet address.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}", + "section": "nodes", + "summary": "destroy_vm", + "description": "Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "destroy-unreferenced-disks", + "type": "boolean", + "required": false, + "description": "If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.", + "default": 0 + }, + { + "name": "purge", + "type": "boolean", + "required": false, + "description": "Remove VMID from configurations, like backup & replication jobs and HA." + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}\nnodes\ndestroy_vm\nDestroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndestroy-unreferenced-disks boolean If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.\npurge boolean Remove VMID from configurations, like backup & replication jobs and HA.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}", + "section": "nodes", + "summary": "vmdiridx", + "description": "Directory index", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}\nnodes\nvmdiridx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent", + "section": "nodes", + "summary": "index", + "description": "QEMU Guest Agent command index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns the list of QEMU Guest Agent commands", + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent\nnodes\nindex\nQEMU Guest Agent command index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent", + "section": "nodes", + "summary": "agent", + "description": "Execute QEMU Guest Agent commands.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "command", + "type": "string", + "required": true, + "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" + ] + } + ], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent\nnodes\nagent\nExecute QEMU Guest Agent commands.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand string The QGA command. 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\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/exec", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/exec", + "section": "nodes", + "summary": "exec", + "description": "Executes the given command in the vm via the guest-agent and returns an object with the pid.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "command", + "type": "array", + "required": true, + "description": "The command as a list of program + arguments." + }, + { + "name": "input-data", + "type": "string", + "required": false, + "description": "Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'." + } + ], + "returns": { + "properties": { + "pid": { + "description": "The PID of the process started by the guest-agent.", + "type": "integer" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/exec\nnodes\nexec\nExecutes the given command in the vm via the guest-agent and returns an object with the pid.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand array The command as a list of program + arguments.\ninput-data string Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/exec-status", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "section": "nodes", + "summary": "exec-status", + "description": "Gets the status of the given pid started by the guest-agent", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "pid", + "type": "integer", + "required": true, + "description": "The PID to query" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/exec-status\nnodes\nexec-status\nGets the status of the given pid started by the guest-agent\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npid integer The PID to query\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/file-read", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/file-read", + "section": "nodes", + "summary": "file-read", + "description": "Reads the given file via guest agent. Is limited to 16777216 bytes.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "file", + "type": "string", + "required": true, + "description": "The path to the file" + }, + { + "name": "count", + "type": "integer", + "required": false, + "description": "Number of bytes to read.", + "default": "16777216", + "minimum": 1 + }, + { + "name": "decode", + "type": "boolean", + "required": false, + "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.", + "default": 1 + }, + { + "name": "offset", + "type": "integer", + "required": false, + "description": "Offset to start reading at", + "default": 0, + "minimum": 0 + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileRead", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/file-read\nnodes\nfile-read\nReads the given file via guest agent. Is limited to 16777216 bytes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfile string The path to the file\ncount integer Number of bytes to read.\ndecode boolean 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.\noffset integer Offset to start reading at\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/file-write", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/file-write", + "section": "nodes", + "summary": "file-write", + "description": "Writes the given file via guest agent.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "content", + "type": "string", + "required": true, + "description": "The content to write into the file." + }, + { + "name": "file", + "type": "string", + "required": true, + "description": "The path to the file." + }, + { + "name": "encode", + "type": "boolean", + "required": false, + "description": "If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.", + "default": 1 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileWrite", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/file-write\nnodes\nfile-write\nWrites the given file via guest agent.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontent string The content to write into the file.\nfile string The path to the file.\nencode boolean If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "section": "nodes", + "summary": "fsfreeze-freeze", + "description": "Execute fsfreeze-freeze.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze\nnodes\nfsfreeze-freeze\nExecute fsfreeze-freeze.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "section": "nodes", + "summary": "fsfreeze-status", + "description": "Execute fsfreeze-status.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status\nnodes\nfsfreeze-status\nExecute fsfreeze-status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "section": "nodes", + "summary": "fsfreeze-thaw", + "description": "Execute fsfreeze-thaw.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw\nnodes\nfsfreeze-thaw\nExecute fsfreeze-thaw.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fstrim", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "section": "nodes", + "summary": "fstrim", + "description": "Execute fstrim.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fstrim\nnodes\nfstrim\nExecute fstrim.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "section": "nodes", + "summary": "get-fsinfo", + "description": "Execute get-fsinfo.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-fsinfo\nnodes\nget-fsinfo\nExecute get-fsinfo.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-host-name", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "section": "nodes", + "summary": "get-host-name", + "description": "Execute get-host-name.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-host-name\nnodes\nget-host-name\nExecute get-host-name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "section": "nodes", + "summary": "get-memory-block-info", + "description": "Execute get-memory-block-info.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info\nnodes\nget-memory-block-info\nExecute get-memory-block-info.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "section": "nodes", + "summary": "get-memory-blocks", + "description": "Execute get-memory-blocks.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks\nnodes\nget-memory-blocks\nExecute get-memory-blocks.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "section": "nodes", + "summary": "get-osinfo", + "description": "Execute get-osinfo.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-osinfo\nnodes\nget-osinfo\nExecute get-osinfo.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-time", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "section": "nodes", + "summary": "get-time", + "description": "Execute get-time.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-time\nnodes\nget-time\nExecute get-time.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-timezone", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "section": "nodes", + "summary": "get-timezone", + "description": "Execute get-timezone.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-timezone\nnodes\nget-timezone\nExecute get-timezone.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-users", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-users", + "section": "nodes", + "summary": "get-users", + "description": "Execute get-users.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-users\nnodes\nget-users\nExecute get-users.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "section": "nodes", + "summary": "get-vcpus", + "description": "Execute get-vcpus.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-vcpus\nnodes\nget-vcpus\nExecute get-vcpus.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/info", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/info", + "section": "nodes", + "summary": "info", + "description": "Execute info.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/info\nnodes\ninfo\nExecute info.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "section": "nodes", + "summary": "network-get-interfaces", + "description": "Execute network-get-interfaces.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces\nnodes\nnetwork-get-interfaces\nExecute network-get-interfaces.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/ping", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/ping", + "section": "nodes", + "summary": "ping", + "description": "Execute ping.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/ping\nnodes\nping\nExecute ping.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/set-user-password", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "section": "nodes", + "summary": "set-user-password", + "description": "Sets the password for the given user to the given password", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "password", + "type": "string", + "required": true, + "description": "The new password." + }, + { + "name": "username", + "type": "string", + "required": true, + "description": "The user to set the password for." + }, + { + "name": "crypted", + "type": "boolean", + "required": false, + "description": "set to 1 if the password has already been passed through crypt()", + "default": 0 + } + ], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/set-user-password\nnodes\nset-user-password\nSets the password for the given user to the given password\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npassword string The new password.\nusername string The user to set the password for.\ncrypted boolean set to 1 if the password has already been passed through crypt()\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/shutdown", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "section": "nodes", + "summary": "shutdown", + "description": "Execute shutdown.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/shutdown\nnodes\nshutdown\nExecute shutdown.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "section": "nodes", + "summary": "suspend-disk", + "description": "Execute suspend-disk.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-disk\nnodes\nsuspend-disk\nExecute suspend-disk.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "section": "nodes", + "summary": "suspend-hybrid", + "description": "Execute suspend-hybrid.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid\nnodes\nsuspend-hybrid\nExecute suspend-hybrid.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "section": "nodes", + "summary": "suspend-ram", + "description": "Execute suspend-ram.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "description": "Returns an object with a single `result` property.", + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-ram\nnodes\nsuspend-ram\nExecute suspend-ram.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/clone", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/clone", + "section": "nodes", + "summary": "clone_vm", + "description": "Create a copy of virtual machine/template.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "newid", + "type": "integer", + "required": true, + "description": "VMID for the clone.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "clone limit from datacenter or storage config" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the new VM." + }, + { + "name": "format", + "type": "string", + "required": false, + "description": "Target format for file storage. Only valid for full clone.", + "enum": [ + "raw", + "qcow2", + "vmdk" + ] + }, + { + "name": "full", + "type": "boolean", + "required": false, + "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." + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "Set a name for the new VM.", + "format": "dns-name" + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Add the new VM to the specified pool.", + "format": "pve-poolid" + }, + { + "name": "snapname", + "type": "string", + "required": false, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Target storage for full clone.", + "format": "pve-storage-id" + }, + { + "name": "target", + "type": "string", + "required": false, + "description": "Target node. Only allowed if the original VM is on shared storage.", + "format": "pve-node" + } + ], + "returns": { + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/clone\nnodes\nclone_vm\nCreate a copy of virtual machine/template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnewid integer VMID for the clone.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndescription string Description for the new VM.\nformat string Target format for file storage. Only valid for full clone. raw qcow2 vmdk\nfull boolean 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.\nname string Set a name for the new VM.\npool string Add the new VM to the specified pool.\nsnapname string The name of the snapshot.\nstorage string Target storage for full clone.\ntarget string Target node. Only allowed if the original VM is on shared storage.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/cloudinit", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "section": "nodes", + "summary": "cloudinit_pending", + "description": "Get the cloudinit configuration with both current and pending values.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/cloudinit\nnodes\ncloudinit_pending\nGet the cloudinit configuration with both current and pending values.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/cloudinit", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "section": "nodes", + "summary": "cloudinit_update", + "description": "Regenerate and change cloudinit config drive.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Cloudinit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/cloudinit\nnodes\ncloudinit_update\nRegenerate and change cloudinit config drive.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/cloudinit/dump", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "section": "nodes", + "summary": "cloudinit_generated_config_dump", + "description": "Get automatically generated cloudinit config.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": true, + "description": "Config type.", + "enum": [ + "user", + "network", + "meta" + ] + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/cloudinit/dump\nnodes\ncloudinit_generated_config_dump\nGet automatically generated cloudinit config.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Config type. user network meta\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/config", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/config", + "section": "nodes", + "summary": "vm_config", + "description": "Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "current", + "type": "boolean", + "required": false, + "description": "Get current values (instead of pending values).", + "default": 0 + }, + { + "name": "snapshot", + "type": "string", + "required": false, + "description": "Fetch config values from given snapshot.", + "format": "pve-configid" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/config\nnodes\nvm_config\nGet the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncurrent boolean Get current values (instead of pending values).\nsnapshot string Fetch config values from given snapshot.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/config", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/config", + "section": "nodes", + "summary": "update_vm_async", + "description": "Set virtual machine options (asynchronous API).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "acpi", + "type": "boolean", + "required": false, + "description": "Enable/disable ACPI.", + "default": 1 + }, + { + "name": "affinity", + "type": "string", + "required": false, + "description": "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format": "pve-cpuset" + }, + { + "name": "agent", + "type": "string", + "required": false, + "description": "Enable/disable communication with the QEMU Guest Agent and its properties." + }, + { + "name": "allow-ksm", + "type": "boolean", + "required": false, + "description": "Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).", + "default": 1 + }, + { + "name": "amd-sev", + "type": "string", + "required": false, + "description": "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format": "pve-qemu-sev-fmt" + }, + { + "name": "arch", + "type": "string", + "required": false, + "description": "Virtual processor architecture. Defaults to the host architecture.", + "enum": [ + "x86_64", + "aarch64" + ] + }, + { + "name": "args", + "type": "string", + "required": false, + "description": "Arbitrary arguments passed to kvm." + }, + { + "name": "audio0", + "type": "string", + "required": false, + "description": "Configure a audio device, useful in combination with QXL/Spice." + }, + { + "name": "autostart", + "type": "boolean", + "required": false, + "description": "Automatic restart after crash (currently ignored).", + "default": 0 + }, + { + "name": "background_delay", + "type": "integer", + "required": false, + "description": "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "minimum": 1, + "maximum": 30 + }, + { + "name": "balloon", + "type": "integer", + "required": false, + "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 + }, + { + "name": "bios", + "type": "string", + "required": false, + "description": "Select BIOS implementation.", + "enum": [ + "seabios", + "ovmf" + ], + "default": "seabios" + }, + { + "name": "boot", + "type": "string", + "required": false, + "description": "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format": "pve-qm-boot" + }, + { + "name": "bootdisk", + "type": "string", + "required": false, + "description": "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format": "pve-qm-bootdisk" + }, + { + "name": "cdrom", + "type": "string", + "required": false, + "description": "This is an alias for option -ide2", + "format": "pve-qm-ide" + }, + { + "name": "cicustom", + "type": "string", + "required": false, + "description": "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format": "pve-qm-cicustom" + }, + { + "name": "cipassword", + "type": "string", + "required": false, + "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." + }, + { + "name": "citype", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "ciupgrade", + "type": "boolean", + "required": false, + "description": "cloud-init: do an automatic package upgrade after the first boot.", + "default": 1 + }, + { + "name": "ciuser", + "type": "string", + "required": false, + "description": "cloud-init: User name to change ssh keys and password for instead of the image's configured default user." + }, + { + "name": "cores", + "type": "integer", + "required": false, + "description": "The number of cores per socket.", + "default": 1, + "minimum": 1 + }, + { + "name": "cpu", + "type": "string", + "required": false, + "description": "Emulated CPU type.", + "format": "pve-vm-cpu-conf" + }, + { + "name": "cpulimit", + "type": "number", + "required": false, + "description": "Limit of CPU usage.", + "default": 0, + "minimum": 0, + "maximum": 128 + }, + { + "name": "cpuunits", + "type": "integer", + "required": false, + "description": "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "default": "cgroup v1: 1024, cgroup v2: 100", + "minimum": 1, + "maximum": 262144 + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications." + }, + { + "name": "efidisk0", + "type": "string", + "required": false, + "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." + }, + { + "name": "force", + "type": "boolean", + "required": false, + "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." + }, + { + "name": "freeze", + "type": "boolean", + "required": false, + "description": "Freeze CPU at startup (use 'c' monitor command to start execution)." + }, + { + "name": "hookscript", + "type": "string", + "required": false, + "description": "Script that will be executed during various steps in the vms lifetime.", + "format": "pve-volume-id" + }, + { + "name": "hostpci[n]", + "type": "string", + "required": false, + "description": "Map host PCI devices into guest.", + "format": "pve-qm-hostpci" + }, + { + "name": "hotplug", + "type": "string", + "required": false, + "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.", + "default": "network,disk,usb", + "format": "pve-hotplug-features" + }, + { + "name": "hugepages", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "ide[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "import-working-storage", + "type": "string", + "required": false, + "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" + }, + { + "name": "intel-tdx", + "type": "string", + "required": false, + "description": "Trusted Domain Extension (TDX) features by Intel CPUs", + "format": "pve-qemu-tdx-fmt" + }, + { + "name": "ipconfig[n]", + "type": "string", + "required": false, + "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.", + "format": "pve-qm-ipconfig" + }, + { + "name": "ivshmem", + "type": "string", + "required": false, + "description": "Inter-VM shared memory. Useful for direct communication between VMs, or to the host." + }, + { + "name": "keephugepages", + "type": "boolean", + "required": false, + "description": "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "default": 0 + }, + { + "name": "keyboard", + "type": "string", + "required": false, + "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" + ], + "default": null + }, + { + "name": "kvm", + "type": "boolean", + "required": false, + "description": "Enable/disable KVM hardware virtualization.", + "default": 1 + }, + { + "name": "localtime", + "type": "boolean", + "required": false, + "description": "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS." + }, + { + "name": "lock", + "type": "string", + "required": false, + "description": "Lock/unlock the VM.", + "enum": [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ] + }, + { + "name": "machine", + "type": "string", + "required": false, + "description": "Specify the QEMU machine." + }, + { + "name": "memory", + "type": "string", + "required": false, + "description": "Memory properties." + }, + { + "name": "migrate_downtime", + "type": "number", + "required": false, + "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).", + "default": 0.1, + "minimum": 0 + }, + { + "name": "migrate_speed", + "type": "integer", + "required": false, + "description": "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "default": 0, + "minimum": 0 + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "Set a name for the VM. Only used on the configuration web interface.", + "format": "dns-name" + }, + { + "name": "nameserver", + "type": "string", + "required": false, + "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" + }, + { + "name": "net[n]", + "type": "string", + "required": false, + "description": "Specify network devices." + }, + { + "name": "numa", + "type": "boolean", + "required": false, + "description": "Enable/disable NUMA.", + "default": 0 + }, + { + "name": "numa[n]", + "type": "string", + "required": false, + "description": "NUMA topology." + }, + { + "name": "onboot", + "type": "boolean", + "required": false, + "description": "Specifies whether a VM will be started during system bootup.", + "default": 0 + }, + { + "name": "ostype", + "type": "string", + "required": false, + "description": "Specify guest operating system.", + "enum": [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "default": "other" + }, + { + "name": "parallel[n]", + "type": "string", + "required": false, + "description": "Map host parallel devices (n is 0 to 2)." + }, + { + "name": "protection", + "type": "boolean", + "required": false, + "description": "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "default": 0 + }, + { + "name": "reboot", + "type": "boolean", + "required": false, + "description": "Allow reboot. If set to '0' the VM exit on reboot.", + "default": 1 + }, + { + "name": "revert", + "type": "string", + "required": false, + "description": "Revert a pending change.", + "format": "pve-configid-list" + }, + { + "name": "rng0", + "type": "string", + "required": false, + "description": "Configure a VirtIO-based Random Number Generator.", + "format": "pve-qm-rng" + }, + { + "name": "sata[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "scsi[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "scsihw", + "type": "string", + "required": false, + "description": "SCSI controller model", + "enum": [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "default": "lsi" + }, + { + "name": "searchdomain", + "type": "string", + "required": false, + "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." + }, + { + "name": "serial[n]", + "type": "string", + "required": false, + "description": "Create a serial device inside the VM (n is 0 to 3)" + }, + { + "name": "shares", + "type": "integer", + "required": false, + "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.", + "default": 1000, + "minimum": 0, + "maximum": 50000 + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + }, + { + "name": "smbios1", + "type": "string", + "required": false, + "description": "Specify SMBIOS type 1 fields.", + "format": "pve-qm-smbios1" + }, + { + "name": "smp", + "type": "integer", + "required": false, + "description": "The number of CPUs. Please use option -sockets instead.", + "default": 1, + "minimum": 1 + }, + { + "name": "sockets", + "type": "integer", + "required": false, + "description": "The number of CPU sockets.", + "default": 1, + "minimum": 1 + }, + { + "name": "spice_enhancements", + "type": "string", + "required": false, + "description": "Configure additional enhancements for SPICE." + }, + { + "name": "sshkeys", + "type": "string", + "required": false, + "description": "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format": "urlencoded" + }, + { + "name": "startdate", + "type": "string", + "required": false, + "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'.", + "default": "now" + }, + { + "name": "startup", + "type": "string", + "required": false, + "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" + }, + { + "name": "tablet", + "type": "boolean", + "required": false, + "description": "Enable/disable the USB tablet device.", + "default": 1 + }, + { + "name": "tags", + "type": "string", + "required": false, + "description": "Tags of the VM. This is only meta information.", + "format": "pve-tag-list" + }, + { + "name": "tdf", + "type": "boolean", + "required": false, + "description": "Enable/disable time drift fix.", + "default": 0 + }, + { + "name": "template", + "type": "boolean", + "required": false, + "description": "Enable/disable Template.", + "default": 0 + }, + { + "name": "tpmstate0", + "type": "string", + "required": false, + "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." + }, + { + "name": "unused[n]", + "type": "string", + "required": false, + "description": "Reference to unused volumes. This is used internally, and should not be modified manually." + }, + { + "name": "usb[n]", + "type": "string", + "required": false, + "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)." + }, + { + "name": "vcpus", + "type": "integer", + "required": false, + "description": "Number of hotplugged vcpus.", + "default": 0, + "minimum": 1 + }, + { + "name": "vga", + "type": "string", + "required": false, + "description": "Configure the VGA hardware." + }, + { + "name": "virtio[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "virtiofs[n]", + "type": "string", + "required": false, + "description": "Configuration for sharing a directory between host and guest using Virtio-fs." + }, + { + "name": "vmgenid", + "type": "string", + "required": false, + "description": "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "default": "1 (autogenerated)" + }, + { + "name": "vmstatestorage", + "type": "string", + "required": false, + "description": "Default storage for VM state volumes/files.", + "format": "pve-storage-id" + }, + { + "name": "watchdog", + "type": "string", + "required": false, + "description": "Create a virtual hardware watchdog device.", + "format": "pve-qm-watchdog" + } + ], + "returns": { + "optional": 1, + "type": "string" + }, + "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 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/config\nnodes\nupdate_vm_async\nSet virtual machine options (asynchronous API).\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nbackground_delay integer Time to wait for the task to finish. We return 'null' if the task finish within that time.\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndelete string A list of settings you want to delete.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nefidisk0 string 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.\nforce boolean 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.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nimport-working-storage string A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrevert string Revert a pending change.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstartdate string 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'.\nstartup string 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.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/config", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/config", + "section": "nodes", + "summary": "update_vm", + "description": "Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "acpi", + "type": "boolean", + "required": false, + "description": "Enable/disable ACPI.", + "default": 1 + }, + { + "name": "affinity", + "type": "string", + "required": false, + "description": "List of host cores used to execute guest processes, for example: 0,5,8-11", + "format": "pve-cpuset" + }, + { + "name": "agent", + "type": "string", + "required": false, + "description": "Enable/disable communication with the QEMU Guest Agent and its properties." + }, + { + "name": "allow-ksm", + "type": "boolean", + "required": false, + "description": "Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).", + "default": 1 + }, + { + "name": "amd-sev", + "type": "string", + "required": false, + "description": "Secure Encrypted Virtualization (SEV) features by AMD CPUs", + "format": "pve-qemu-sev-fmt" + }, + { + "name": "arch", + "type": "string", + "required": false, + "description": "Virtual processor architecture. Defaults to the host architecture.", + "enum": [ + "x86_64", + "aarch64" + ] + }, + { + "name": "args", + "type": "string", + "required": false, + "description": "Arbitrary arguments passed to kvm." + }, + { + "name": "audio0", + "type": "string", + "required": false, + "description": "Configure a audio device, useful in combination with QXL/Spice." + }, + { + "name": "autostart", + "type": "boolean", + "required": false, + "description": "Automatic restart after crash (currently ignored).", + "default": 0 + }, + { + "name": "balloon", + "type": "integer", + "required": false, + "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 + }, + { + "name": "bios", + "type": "string", + "required": false, + "description": "Select BIOS implementation.", + "enum": [ + "seabios", + "ovmf" + ], + "default": "seabios" + }, + { + "name": "boot", + "type": "string", + "required": false, + "description": "Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.", + "format": "pve-qm-boot" + }, + { + "name": "bootdisk", + "type": "string", + "required": false, + "description": "Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.", + "format": "pve-qm-bootdisk" + }, + { + "name": "cdrom", + "type": "string", + "required": false, + "description": "This is an alias for option -ide2", + "format": "pve-qm-ide" + }, + { + "name": "cicustom", + "type": "string", + "required": false, + "description": "cloud-init: Specify custom files to replace the automatically generated ones at start.", + "format": "pve-qm-cicustom" + }, + { + "name": "cipassword", + "type": "string", + "required": false, + "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." + }, + { + "name": "citype", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "ciupgrade", + "type": "boolean", + "required": false, + "description": "cloud-init: do an automatic package upgrade after the first boot.", + "default": 1 + }, + { + "name": "ciuser", + "type": "string", + "required": false, + "description": "cloud-init: User name to change ssh keys and password for instead of the image's configured default user." + }, + { + "name": "cores", + "type": "integer", + "required": false, + "description": "The number of cores per socket.", + "default": 1, + "minimum": 1 + }, + { + "name": "cpu", + "type": "string", + "required": false, + "description": "Emulated CPU type.", + "format": "pve-vm-cpu-conf" + }, + { + "name": "cpulimit", + "type": "number", + "required": false, + "description": "Limit of CPU usage.", + "default": 0, + "minimum": 0, + "maximum": 128 + }, + { + "name": "cpuunits", + "type": "integer", + "required": false, + "description": "CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.", + "default": "cgroup v1: 1024, cgroup v2: 100", + "minimum": 1, + "maximum": 262144 + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications." + }, + { + "name": "efidisk0", + "type": "string", + "required": false, + "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." + }, + { + "name": "force", + "type": "boolean", + "required": false, + "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." + }, + { + "name": "freeze", + "type": "boolean", + "required": false, + "description": "Freeze CPU at startup (use 'c' monitor command to start execution)." + }, + { + "name": "hookscript", + "type": "string", + "required": false, + "description": "Script that will be executed during various steps in the vms lifetime.", + "format": "pve-volume-id" + }, + { + "name": "hostpci[n]", + "type": "string", + "required": false, + "description": "Map host PCI devices into guest.", + "format": "pve-qm-hostpci" + }, + { + "name": "hotplug", + "type": "string", + "required": false, + "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.", + "default": "network,disk,usb", + "format": "pve-hotplug-features" + }, + { + "name": "hugepages", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "ide[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "intel-tdx", + "type": "string", + "required": false, + "description": "Trusted Domain Extension (TDX) features by Intel CPUs", + "format": "pve-qemu-tdx-fmt" + }, + { + "name": "ipconfig[n]", + "type": "string", + "required": false, + "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.", + "format": "pve-qm-ipconfig" + }, + { + "name": "ivshmem", + "type": "string", + "required": false, + "description": "Inter-VM shared memory. Useful for direct communication between VMs, or to the host." + }, + { + "name": "keephugepages", + "type": "boolean", + "required": false, + "description": "Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.", + "default": 0 + }, + { + "name": "keyboard", + "type": "string", + "required": false, + "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" + ], + "default": null + }, + { + "name": "kvm", + "type": "boolean", + "required": false, + "description": "Enable/disable KVM hardware virtualization.", + "default": 1 + }, + { + "name": "localtime", + "type": "boolean", + "required": false, + "description": "Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS." + }, + { + "name": "lock", + "type": "string", + "required": false, + "description": "Lock/unlock the VM.", + "enum": [ + "backup", + "clone", + "create", + "migrate", + "rollback", + "snapshot", + "snapshot-delete", + "suspending", + "suspended" + ] + }, + { + "name": "machine", + "type": "string", + "required": false, + "description": "Specify the QEMU machine." + }, + { + "name": "memory", + "type": "string", + "required": false, + "description": "Memory properties." + }, + { + "name": "migrate_downtime", + "type": "number", + "required": false, + "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).", + "default": 0.1, + "minimum": 0 + }, + { + "name": "migrate_speed", + "type": "integer", + "required": false, + "description": "Set maximum speed (in MB/s) for migrations. Value 0 is no limit.", + "default": 0, + "minimum": 0 + }, + { + "name": "name", + "type": "string", + "required": false, + "description": "Set a name for the VM. Only used on the configuration web interface.", + "format": "dns-name" + }, + { + "name": "nameserver", + "type": "string", + "required": false, + "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" + }, + { + "name": "net[n]", + "type": "string", + "required": false, + "description": "Specify network devices." + }, + { + "name": "numa", + "type": "boolean", + "required": false, + "description": "Enable/disable NUMA.", + "default": 0 + }, + { + "name": "numa[n]", + "type": "string", + "required": false, + "description": "NUMA topology." + }, + { + "name": "onboot", + "type": "boolean", + "required": false, + "description": "Specifies whether a VM will be started during system bootup.", + "default": 0 + }, + { + "name": "ostype", + "type": "string", + "required": false, + "description": "Specify guest operating system.", + "enum": [ + "other", + "wxp", + "w2k", + "w2k3", + "w2k8", + "wvista", + "win7", + "win8", + "win10", + "win11", + "l24", + "l26", + "solaris" + ], + "default": "other" + }, + { + "name": "parallel[n]", + "type": "string", + "required": false, + "description": "Map host parallel devices (n is 0 to 2)." + }, + { + "name": "protection", + "type": "boolean", + "required": false, + "description": "Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.", + "default": 0 + }, + { + "name": "reboot", + "type": "boolean", + "required": false, + "description": "Allow reboot. If set to '0' the VM exit on reboot.", + "default": 1 + }, + { + "name": "revert", + "type": "string", + "required": false, + "description": "Revert a pending change.", + "format": "pve-configid-list" + }, + { + "name": "rng0", + "type": "string", + "required": false, + "description": "Configure a VirtIO-based Random Number Generator.", + "format": "pve-qm-rng" + }, + { + "name": "sata[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "scsi[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "scsihw", + "type": "string", + "required": false, + "description": "SCSI controller model", + "enum": [ + "lsi", + "lsi53c810", + "virtio-scsi-pci", + "virtio-scsi-single", + "megasas", + "pvscsi" + ], + "default": "lsi" + }, + { + "name": "searchdomain", + "type": "string", + "required": false, + "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." + }, + { + "name": "serial[n]", + "type": "string", + "required": false, + "description": "Create a serial device inside the VM (n is 0 to 3)" + }, + { + "name": "shares", + "type": "integer", + "required": false, + "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.", + "default": 1000, + "minimum": 0, + "maximum": 50000 + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + }, + { + "name": "smbios1", + "type": "string", + "required": false, + "description": "Specify SMBIOS type 1 fields.", + "format": "pve-qm-smbios1" + }, + { + "name": "smp", + "type": "integer", + "required": false, + "description": "The number of CPUs. Please use option -sockets instead.", + "default": 1, + "minimum": 1 + }, + { + "name": "sockets", + "type": "integer", + "required": false, + "description": "The number of CPU sockets.", + "default": 1, + "minimum": 1 + }, + { + "name": "spice_enhancements", + "type": "string", + "required": false, + "description": "Configure additional enhancements for SPICE." + }, + { + "name": "sshkeys", + "type": "string", + "required": false, + "description": "cloud-init: Setup public SSH keys (one key per line, OpenSSH format).", + "format": "urlencoded" + }, + { + "name": "startdate", + "type": "string", + "required": false, + "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'.", + "default": "now" + }, + { + "name": "startup", + "type": "string", + "required": false, + "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" + }, + { + "name": "tablet", + "type": "boolean", + "required": false, + "description": "Enable/disable the USB tablet device.", + "default": 1 + }, + { + "name": "tags", + "type": "string", + "required": false, + "description": "Tags of the VM. This is only meta information.", + "format": "pve-tag-list" + }, + { + "name": "tdf", + "type": "boolean", + "required": false, + "description": "Enable/disable time drift fix.", + "default": 0 + }, + { + "name": "template", + "type": "boolean", + "required": false, + "description": "Enable/disable Template.", + "default": 0 + }, + { + "name": "tpmstate0", + "type": "string", + "required": false, + "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." + }, + { + "name": "unused[n]", + "type": "string", + "required": false, + "description": "Reference to unused volumes. This is used internally, and should not be modified manually." + }, + { + "name": "usb[n]", + "type": "string", + "required": false, + "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)." + }, + { + "name": "vcpus", + "type": "integer", + "required": false, + "description": "Number of hotplugged vcpus.", + "default": 0, + "minimum": 1 + }, + { + "name": "vga", + "type": "string", + "required": false, + "description": "Configure the VGA hardware." + }, + { + "name": "virtio[n]", + "type": "string", + "required": false, + "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." + }, + { + "name": "virtiofs[n]", + "type": "string", + "required": false, + "description": "Configuration for sharing a directory between host and guest using Virtio-fs." + }, + { + "name": "vmgenid", + "type": "string", + "required": false, + "description": "Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.", + "default": "1 (autogenerated)" + }, + { + "name": "vmstatestorage", + "type": "string", + "required": false, + "description": "Default storage for VM state volumes/files.", + "format": "pve-storage-id" + }, + { + "name": "watchdog", + "type": "string", + "required": false, + "description": "Create a virtual hardware watchdog device.", + "format": "pve-qm-watchdog" + } + ], + "returns": { + "type": "null" + }, + "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 + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/config\nnodes\nupdate_vm\nSet virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndelete string A list of settings you want to delete.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nefidisk0 string 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.\nforce boolean 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.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrevert string Revert a pending change.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstartdate string 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'.\nstartup string 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.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/dbus-vmstate", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/dbus-vmstate", + "section": "nodes", + "summary": "dbus_vmstate", + "description": "Control the dbus-vmstate helper for a given running VM.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Action to perform on the DBus VMState helper.", + "enum": [ + "start", + "stop" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/dbus-vmstate\nnodes\ndbus_vmstate\nControl the dbus-vmstate helper for a given running VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Action to perform on the DBus VMState helper. start stop\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/feature", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/feature", + "section": "nodes", + "summary": "vm_feature", + "description": "Check if feature for virtual machine is available.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "feature", + "type": "string", + "required": true, + "description": "Feature to check.", + "enum": [ + "snapshot", + "clone", + "copy" + ] + }, + { + "name": "snapname", + "type": "string", + "required": false, + "description": "The name of the snapshot.", + "format": "pve-configid" + } + ], + "returns": { + "properties": { + "hasFeature": { + "type": "boolean" + }, + "nodes": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/feature\nnodes\nvm_feature\nCheck if feature for virtual machine is available.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfeature string Feature to check. snapshot clone copy\nsnapname string The name of the snapshot.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall", + "section": "nodes", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/aliases", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "get_aliases", + "description": "List aliases", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/aliases\nnodes\nget_aliases\nList aliases\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/aliases", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "create_alias", + "description": "Create IP or Network Alias.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDR" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "comment", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/aliases\nnodes\ncreate_alias\nCreate IP or Network Alias.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "remove_alias", + "description": "Remove IP or Network alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "read_alias", + "description": "Read alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nread_alias\nRead alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "update_alias", + "description": "Update IP or Network alias.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "Alias name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDR" + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "rename", + "type": "string", + "required": false, + "description": "Rename an existing alias." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "ipset_index", + "description": "List IPSets", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset\nnodes\nipset_index\nList IPSets\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/ipset", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "create_ipset", + "description": "Create new IPSet", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "rename", + "type": "string", + "required": false, + "description": "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/ipset\nnodes\ncreate_ipset\nCreate new IPSet\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "delete_ipset", + "description": "Delete IPSet", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Delete all members of the IPSet, if there are any." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\ndelete_ipset\nDelete IPSet\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce boolean Delete all members of the IPSet, if there are any.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "get_ipset", + "description": "List IPSet content", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\nget_ipset\nList IPSet content\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "create_ip", + "description": "Add IP or Network to IPSet.", + "pathParameters": [ + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "nomatch", + "type": "boolean", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "remove_ip", + "description": "Remove IP or Network from IPSet.", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "read_ip", + "description": "Read IP or Network settings from IPSet.", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "update_ip", + "description": "Update IP or Network settings", + "pathParameters": [ + { + "name": "cidr", + "type": "string", + "required": true, + "description": "Network/IP specification in CIDR format.", + "format": "IPorCIDRorAlias" + }, + { + "name": "name", + "type": "string", + "required": true, + "description": "IP set name." + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "nomatch", + "type": "boolean", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/log", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/log", + "section": "nodes", + "summary": "log", + "description": "Read firewall log", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "limit", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "since", + "type": "integer", + "required": false, + "description": "Display log since this UNIX epoch.", + "minimum": 0 + }, + { + "name": "start", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "until", + "type": "integer", + "required": false, + "description": "Display log until this UNIX epoch.", + "minimum": 0 + } + ], + "returns": { + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/options", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "section": "nodes", + "summary": "get_options", + "description": "Get VM firewall options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/options\nnodes\nget_options\nGet VM firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/options", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "section": "nodes", + "summary": "set_options", + "description": "Set Firewall options.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dhcp", + "type": "boolean", + "required": false, + "description": "Enable DHCP.", + "default": 0 + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "enable", + "type": "boolean", + "required": false, + "description": "Enable/disable firewall rules.", + "default": 0 + }, + { + "name": "ipfilter", + "type": "boolean", + "required": false, + "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." + }, + { + "name": "log_level_in", + "type": "string", + "required": false, + "description": "Log level for incoming traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "log_level_out", + "type": "string", + "required": false, + "description": "Log level for outgoing traffic.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macfilter", + "type": "boolean", + "required": false, + "description": "Enable/disable MAC address filter.", + "default": 1 + }, + { + "name": "ndp", + "type": "boolean", + "required": false, + "description": "Enable NDP (Neighbor Discovery Protocol).", + "default": 1 + }, + { + "name": "policy_in", + "type": "string", + "required": false, + "description": "Input policy.", + "enum": [ + "ACCEPT", + "REJECT", + "DROP" + ] + }, + { + "name": "policy_out", + "type": "string", + "required": false, + "description": "Output policy.", + "enum": [ + "ACCEPT", + "REJECT", + "DROP" + ] + }, + { + "name": "radv", + "type": "boolean", + "required": false, + "description": "Allow sending Router Advertisement." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndelete string A list of settings you want to delete.\ndhcp boolean Enable DHCP.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nipfilter boolean 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.\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nmacfilter boolean Enable/disable MAC address filter.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP\nradv boolean Allow sending Router Advertisement.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/refs", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/refs", + "section": "nodes", + "summary": "refs", + "description": "Lists possible IPSet/Alias reference which are allowed in source/dest properties.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list references of specified type.", + "enum": [ + "alias", + "ipset" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/refs\nnodes\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Only list references of specified type. alias ipset\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/rules", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "section": "nodes", + "summary": "get_rules", + "description": "List rules.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/rules", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "section": "nodes", + "summary": "create_rule", + "description": "Create new rule.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": true, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "delete_rule", + "description": "Delete rule.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "get_rule", + "description": "Get single rule data.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "update_rule", + "description": "Modify rule data.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "pos", + "type": "integer", + "required": false, + "description": "Update rule at position .", + "minimum": 0 + } + ], + "requestParameters": [ + { + "name": "action", + "type": "string", + "required": false, + "description": "Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name." + }, + { + "name": "comment", + "type": "string", + "required": false, + "description": "Descriptive comment." + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "dest", + "type": "string", + "required": false, + "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" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "dport", + "type": "string", + "required": false, + "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" + }, + { + "name": "enable", + "type": "integer", + "required": false, + "description": "Flag to enable/disable a rule.", + "minimum": 0 + }, + { + "name": "icmp-type", + "type": "string", + "required": false, + "description": "Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.", + "format": "pve-fw-icmp-type-spec" + }, + { + "name": "iface", + "type": "string", + "required": false, + "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" + }, + { + "name": "log", + "type": "string", + "required": false, + "description": "Log level for firewall rule.", + "enum": [ + "emerg", + "alert", + "crit", + "err", + "warning", + "notice", + "info", + "debug", + "nolog" + ] + }, + { + "name": "macro", + "type": "string", + "required": false, + "description": "Use predefined standard macro." + }, + { + "name": "moveto", + "type": "integer", + "required": false, + "description": "Move rule to new position . Other arguments are ignored.", + "minimum": 0 + }, + { + "name": "proto", + "type": "string", + "required": false, + "description": "IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.", + "format": "pve-fw-protocol-spec" + }, + { + "name": "source", + "type": "string", + "required": false, + "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" + }, + { + "name": "sport", + "type": "string", + "required": false, + "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" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Rule type.", + "enum": [ + "in", + "out", + "forward", + "group" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/migrate", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm_precondition", + "description": "Get preconditions for migration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "target", + "type": "string", + "required": false, + "description": "Target node.", + "format": "pve-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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/migrate\nnodes\nmigrate_vm_precondition\nGet preconditions for migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/migrate", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm", + "description": "Migrate virtual machine. Creates a new migration task.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "target", + "type": "string", + "required": true, + "description": "Target node.", + "format": "pve-node" + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "migrate limit from datacenter or storage config" + }, + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Allow to migrate VMs which use local devices. Only root may use this option." + }, + { + "name": "migration_network", + "type": "string", + "required": false, + "description": "CIDR of the (sub) network that is used for migration.", + "format": "CIDR" + }, + { + "name": "migration_type", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "online", + "type": "boolean", + "required": false, + "description": "Use online/live migration if VM is running. Ignored if VM is stopped." + }, + { + "name": "targetstorage", + "type": "string", + "required": false, + "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" + }, + { + "name": "with-conntrack-state", + "type": "boolean", + "required": false, + "description": "Whether to migrate conntrack entries for running VMs.", + "default": 0 + }, + { + "name": "with-local-disks", + "type": "boolean", + "required": false, + "description": "Enable live storage migration for local disk" + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/migrate\nnodes\nmigrate_vm\nMigrate virtual machine. Creates a new migration task.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\nforce boolean Allow to migrate VMs which use local devices. Only root may use this option.\nmigration_network string CIDR of the (sub) network that is used for migration.\nmigration_type string Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. secure insecure\nonline boolean Use online/live migration if VM is running. Ignored if VM is stopped.\ntargetstorage string 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.\nwith-conntrack-state boolean Whether to migrate conntrack entries for running VMs.\nwith-local-disks boolean Enable live storage migration for local disk\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/monitor", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/monitor", + "section": "nodes", + "summary": "monitor", + "description": "Execute QEMU monitor commands.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "command", + "type": "string", + "required": true, + "description": "The monitor command." + } + ], + "returns": { + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/monitor\nnodes\nmonitor\nExecute QEMU monitor commands.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand string The monitor command.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/move_disk", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/move_disk", + "section": "nodes", + "summary": "move_vm_disk", + "description": "Move volume to different storage or to a different VM.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "disk", + "type": "string", + "required": true, + "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" + ] + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "move limit from datacenter or storage config" + }, + { + "name": "delete", + "type": "boolean", + "required": false, + "description": "Delete the original disk after successful copy. By default the original disk is kept as unused disk.", + "default": 0 + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications." + }, + { + "name": "format", + "type": "string", + "required": false, + "description": "Target Format.", + "enum": [ + "raw", + "qcow2", + "vmdk" + ] + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Target storage.", + "format": "pve-storage-id" + }, + { + "name": "target-digest", + "type": "string", + "required": false, + "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." + }, + { + "name": "target-disk", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "target-vmid", + "type": "integer", + "required": false, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "returns": { + "description": "the task ID.", + "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 disk to another VM, you need the permissions on the target VM as well." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/move_disk\nnodes\nmove_vm_disk\nMove volume to different storage or to a different VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to move. 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\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndelete boolean Delete the original disk after successful copy. By default the original disk is kept as unused disk.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nformat string Target Format. raw qcow2 vmdk\nstorage string Target storage.\ntarget-digest string Prevent changes if the current config file of the target VM has a different SHA1 digest. This can be used to detect concurrent modifications.\ntarget-disk string The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key. 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\ntarget-vmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/mtunnel", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/mtunnel", + "section": "nodes", + "summary": "mtunnel", + "description": "Migration tunnel endpoint - only for internal use by VM migration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "bridges", + "type": "string", + "required": false, + "description": "List of network bridges to check availability. Will be checked again for actually used bridges during migration.", + "format": "pve-bridge-id-list" + }, + { + "name": "storages", + "type": "string", + "required": false, + "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" + } + ], + "returns": { + "additionalProperties": 0, + "properties": { + "socket": { + "type": "string" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + } + } + }, + "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." + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/mtunnel\nnodes\nmtunnel\nMigration tunnel endpoint - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nbridges string List of network bridges to check availability. Will be checked again for actually used bridges during migration.\nstorages string List of storages to check permission and availability. Will be checked again for all actually used storages during migration.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "section": "nodes", + "summary": "mtunnelwebsocket", + "description": "Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "socket", + "type": "string", + "required": true, + "description": "unix socket to forward to" + }, + { + "name": "ticket", + "type": "string", + "required": true, + "description": "ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command" + } + ], + "returns": { + "properties": { + "port": { + "optional": 1, + "type": "string" + }, + "socket": { + "optional": 1, + "type": "string" + } + }, + "type": "object" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/mtunnelwebsocket\nnodes\nmtunnelwebsocket\nMigration tunnel endpoint for websocket upgrade - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsocket string unix socket to forward to\nticket string ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/pending", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/pending", + "section": "nodes", + "summary": "vm_pending", + "description": "Get the virtual machine configuration with both current and pending values.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/pending\nnodes\nvm_pending\nGet the virtual machine configuration with both current and pending values.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/remote_migrate", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/remote_migrate", + "section": "nodes", + "summary": "remote_migrate_vm", + "description": "Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "target-bridge", + "type": "string", + "required": true, + "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" + }, + { + "name": "target-endpoint", + "type": "string", + "required": true, + "description": "Remote target endpoint", + "format": "proxmox-remote" + }, + { + "name": "target-storage", + "type": "string", + "required": true, + "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" + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Override I/O bandwidth limit (in KiB/s).", + "default": "migrate limit from datacenter or storage config" + }, + { + "name": "delete", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "online", + "type": "boolean", + "required": false, + "description": "Use online/live migration if VM is running. Ignored if VM is stopped." + }, + { + "name": "target-vmid", + "type": "integer", + "required": false, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/remote_migrate\nnodes\nremote_migrate_vm\nMigrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget-bridge string 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.\ntarget-endpoint string Remote target endpoint\ntarget-storage string 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.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndelete boolean 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.\nonline boolean Use online/live migration if VM is running. Ignored if VM is stopped.\ntarget-vmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/resize", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/resize", + "section": "nodes", + "summary": "resize_vm", + "description": "Extend volume size.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "disk", + "type": "string", + "required": true, + "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" + ] + }, + { + "name": "size", + "type": "string", + "required": true, + "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." + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications." + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/resize\nnodes\nresize_vm\nExtend volume size.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to resize. 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\nsize string 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.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/rrd", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/rrd", + "section": "nodes", + "summary": "rrd", + "description": "Read VM RRD statistics (returns PNG)", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "ds", + "type": "string", + "required": true, + "description": "The list of datasources you want to display.", + "format": "pve-configid-list" + }, + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/rrd\nnodes\nrrd\nRead VM RRD statistics (returns PNG)\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/rrddata", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/rrddata", + "section": "nodes", + "summary": "rrddata", + "description": "Read VM RRD statistics", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/rrddata\nnodes\nrrddata\nRead VM RRD statistics\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/sendkey", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/sendkey", + "section": "nodes", + "summary": "vm_sendkey", + "description": "Send key event to virtual machine.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "key", + "type": "string", + "required": true, + "description": "The key (qemu monitor encoding)." + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/sendkey\nnodes\nvm_sendkey\nSend key event to virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nkey string The key (qemu monitor encoding).\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/snapshot", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "section": "nodes", + "summary": "snapshot_list", + "description": "List all snapshots.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/snapshot\nnodes\nsnapshot_list\nList all snapshots.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/snapshot", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "section": "nodes", + "summary": "snapshot", + "description": "Snapshot a VM.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "description", + "type": "string", + "required": false, + "description": "A textual description or comment." + }, + { + "name": "vmstate", + "type": "boolean", + "required": false, + "description": "Save the vmstate" + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/snapshot\nnodes\nsnapshot\nSnapshot a VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsnapname string The name of the snapshot.\ndescription string A textual description or comment.\nvmstate boolean Save the vmstate\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "delsnapshot", + "description": "Delete a VM snapshot.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "For removal from config file, even if removing disk snapshots fails." + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}\nnodes\ndelsnapshot\nDelete a VM snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nforce boolean For removal from config file, even if removing disk snapshots fails.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "snapshot_cmd_idx", + "description": "snapshot_cmd_idx", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{cmd}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}\nnodes\nsnapshot_cmd_idx\nsnapshot_cmd_idx\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "get_snapshot_config", + "description": "Get snapshot configuration", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config\nnodes\nget_snapshot_config\nGet snapshot configuration\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "update_snapshot_config", + "description": "Update snapshot metadata.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "description", + "type": "string", + "required": false, + "description": "A textual description or comment." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config\nnodes\nupdate_snapshot_config\nUpdate snapshot metadata.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ndescription string A textual description or comment.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "section": "nodes", + "summary": "rollback", + "description": "Rollback VM state to specified snapshot.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "snapname", + "type": "string", + "required": true, + "description": "The name of the snapshot.", + "format": "pve-configid" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "start", + "type": "boolean", + "required": false, + "description": "Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)", + "default": 0 + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback\nnodes\nrollback\nRollback VM state to specified snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nstart boolean Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/spiceproxy", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/spiceproxy", + "section": "nodes", + "summary": "spiceproxy", + "description": "Returns a SPICE configuration to connect to the VM.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "proxy", + "type": "string", + "required": false, + "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" + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/spiceproxy\nnodes\nspiceproxy\nReturns a SPICE configuration to connect to the VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nproxy string 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).\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/status", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/status", + "section": "nodes", + "summary": "vmcmdidx", + "description": "Directory index", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/status\nnodes\nvmcmdidx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/status/current", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/status/current", + "section": "nodes", + "summary": "vm_status", + "description": "Get virtual machine status.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/status/current\nnodes\nvm_status\nGet virtual machine status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/reboot", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/reboot", + "section": "nodes", + "summary": "vm_reboot", + "description": "Reboot the VM by shutting it down, and starting it again. Applies pending changes.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Wait maximal timeout seconds for the shutdown.", + "minimum": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/reboot\nnodes\nvm_reboot\nReboot the VM by shutting it down, and starting it again. Applies pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeout integer Wait maximal timeout seconds for the shutdown.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/reset", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/reset", + "section": "nodes", + "summary": "vm_reset", + "description": "Reset virtual machine.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/reset\nnodes\nvm_reset\nReset virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/resume", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/resume", + "section": "nodes", + "summary": "vm_resume", + "description": "Resume virtual machine.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "nocheck", + "type": "boolean", + "required": false + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/resume\nnodes\nvm_resume\nResume virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnocheck boolean\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/shutdown", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/shutdown", + "section": "nodes", + "summary": "vm_shutdown", + "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.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "forceStop", + "type": "boolean", + "required": false, + "description": "Make sure the VM stops.", + "default": 0 + }, + { + "name": "keepActive", + "type": "boolean", + "required": false, + "description": "Do not deactivate storage volumes.", + "default": 0 + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Wait maximal timeout seconds.", + "minimum": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/shutdown\nnodes\nvm_shutdown\nShutdown 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.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforceStop boolean Make sure the VM stops.\nkeepActive boolean Do not deactivate storage volumes.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ntimeout integer Wait maximal timeout seconds.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/start", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/start", + "section": "nodes", + "summary": "vm_start", + "description": "Start virtual machine.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "force-cpu", + "type": "string", + "required": false, + "description": "Override QEMU's -cpu argument with the given string." + }, + { + "name": "machine", + "type": "string", + "required": false, + "description": "Specify the QEMU machine." + }, + { + "name": "migratedfrom", + "type": "string", + "required": false, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "migration_network", + "type": "string", + "required": false, + "description": "CIDR of the (sub) network that is used for migration.", + "format": "CIDR" + }, + { + "name": "migration_type", + "type": "string", + "required": false, + "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" + ] + }, + { + "name": "nets-host-mtu", + "type": "string", + "required": false, + "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." + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + }, + { + "name": "stateuri", + "type": "string", + "required": false, + "description": "Some command save/restore state from this location." + }, + { + "name": "targetstorage", + "type": "string", + "required": false, + "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" + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Wait maximal timeout seconds.", + "default": "max(30, vm memory in GiB)", + "minimum": 0 + }, + { + "name": "with-conntrack-state", + "type": "boolean", + "required": false, + "description": "Whether to migrate conntrack entries for running VMs.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/start\nnodes\nvm_start\nStart virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce-cpu string Override QEMU's -cpu argument with the given string.\nmachine string Specify the QEMU machine.\nmigratedfrom string The cluster node name.\nmigration_network string CIDR of the (sub) network that is used for migration.\nmigration_type string Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. secure insecure\nnets-host-mtu string 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nstateuri string Some command save/restore state from this location.\ntargetstorage string 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.\ntimeout integer Wait maximal timeout seconds.\nwith-conntrack-state boolean Whether to migrate conntrack entries for running VMs.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstart\nboot\npower on" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/stop", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/stop", + "section": "nodes", + "summary": "vm_stop", + "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.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "keepActive", + "type": "boolean", + "required": false, + "description": "Do not deactivate storage volumes.", + "default": 0 + }, + { + "name": "migratedfrom", + "type": "string", + "required": false, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "overrule-shutdown", + "type": "boolean", + "required": false, + "description": "Try to abort active 'qmshutdown' tasks before stopping.", + "default": 0 + }, + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Wait maximal timeout seconds.", + "minimum": 0 + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/stop\nnodes\nvm_stop\nStop 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.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nkeepActive boolean Do not deactivate storage volumes.\nmigratedfrom string The cluster node name.\noverrule-shutdown boolean Try to abort active 'qmshutdown' tasks before stopping.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ntimeout integer Wait maximal timeout seconds.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/suspend", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/suspend", + "section": "nodes", + "summary": "vm_suspend", + "description": "Suspend virtual machine.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "skiplock", + "type": "boolean", + "required": false, + "description": "Ignore locks - only root is allowed to use this option." + }, + { + "name": "statestorage", + "type": "string", + "required": false, + "description": "The storage for the VM state", + "format": "pve-storage-id" + }, + { + "name": "todisk", + "type": "boolean", + "required": false, + "description": "If set, suspends the VM to disk. Will be resumed on next VM start.", + "default": 0 + } + ], + "returns": { + "type": "string" + }, + "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." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/suspend\nnodes\nvm_suspend\nSuspend virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nstatestorage string The storage for the VM state\ntodisk boolean If set, suspends the VM to disk. Will be resumed on next VM start.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/template", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/template", + "section": "nodes", + "summary": "template", + "description": "Create a Template.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "disk", + "type": "string", + "required": false, + "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" + ] + } + ], + "returns": { + "description": "the task ID.", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description": "You need 'VM.Allocate' permissions on /vms/{vmid}" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/template\nnodes\ntemplate\nCreate a Template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string If you want to convert only 1 disk to base image. 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\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/termproxy", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/termproxy", + "section": "nodes", + "summary": "termproxy", + "description": "Creates a TCP proxy connections.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "serial", + "type": "string", + "required": false, + "description": "opens a serial terminal (defaults to display)", + "enum": [ + "serial0", + "serial1", + "serial2", + "serial3" + ] + } + ], + "returns": { + "additionalProperties": 0, + "properties": { + "port": { + "type": "integer" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + }, + "user": { + "type": "string" + } + } + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/termproxy\nnodes\ntermproxy\nCreates a TCP proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nserial string opens a serial terminal (defaults to display) serial0 serial1 serial2 serial3\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/unlink", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/unlink", + "section": "nodes", + "summary": "unlink", + "description": "Unlink/delete disk images.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "idlist", + "type": "string", + "required": true, + "description": "A list of disk IDs you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "force", + "type": "boolean", + "required": false, + "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." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/unlink\nnodes\nunlink\nUnlink/delete disk images.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nidlist string A list of disk IDs you want to delete.\nforce boolean 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.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/vncproxy", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/vncproxy", + "section": "nodes", + "summary": "vncproxy", + "description": "Creates a TCP VNC proxy connections.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "generate-password", + "type": "boolean", + "required": false, + "description": "Deprecated, do not use. Password is generated when required.", + "default": 0 + }, + { + "name": "websocket", + "type": "boolean", + "required": false, + "description": "Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible)." + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/vncproxy\nnodes\nvncproxy\nCreates a TCP VNC proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ngenerate-password boolean Deprecated, do not use. Password is generated when required.\nwebsocket boolean Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible).\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/vncwebsocket", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "section": "nodes", + "summary": "vncwebsocket", + "description": "Opens a websocket for VNC traffic.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "The (unique) ID of the VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "requestParameters": [ + { + "name": "port", + "type": "integer", + "required": true, + "description": "Port number returned by previous vncproxy call.", + "minimum": 5900, + "maximum": 5999 + }, + { + "name": "vncticket", + "type": "string", + "required": true, + "description": "Ticket from previous call to vncproxy." + } + ], + "returns": { + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nport integer Port number returned by previous vncproxy call.\nvncticket string Ticket from previous call to vncproxy.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/query-oci-repo-tags", + "method": "GET", + "path": "/nodes/{node}/query-oci-repo-tags", + "section": "nodes", + "summary": "query_oci_repo_tags", + "description": "List all tags for an OCI repository reference.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "reference", + "type": "string", + "required": true, + "description": "The reference to the repository to query tags from." + } + ], + "returns": { + "items": { + "type": "string" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/query-oci-repo-tags\nnodes\nquery_oci_repo_tags\nList all tags for an OCI repository reference.\nnode string The cluster node name.\nreference string The reference to the repository to query tags from." + }, + { + "id": "GET /nodes/{node}/query-url-metadata", + "method": "GET", + "path": "/nodes/{node}/query-url-metadata", + "section": "nodes", + "summary": "query_url_metadata", + "description": "Query metadata of an URL: file size, file name and mime type.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "url", + "type": "string", + "required": true, + "description": "The URL to query the metadata from." + }, + { + "name": "verify-certificates", + "type": "boolean", + "required": false, + "description": "If false, no SSL/TLS certificates will be verified.", + "default": 1 + } + ], + "returns": { + "properties": { + "filename": { + "optional": 1, + "type": "string" + }, + "mimetype": { + "optional": 1, + "type": "string" + }, + "size": { + "optional": 1, + "renderer": "bytes", + "type": "integer" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/query-url-metadata\nnodes\nquery_url_metadata\nQuery metadata of an URL: file size, file name and mime type.\nnode string The cluster node name.\nurl string The URL to query the metadata from.\nverify-certificates boolean If false, no SSL/TLS certificates will be verified." + }, + { + "id": "GET /nodes/{node}/replication", + "method": "GET", + "path": "/nodes/{node}/replication", + "section": "nodes", + "summary": "status", + "description": "List status of all replication jobs on this node.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "guest", + "type": "integer", + "required": false, + "description": "Only list replication jobs for this guest.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "returns": { + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/replication\nnodes\nstatus\nList status of all replication jobs on this node.\nnode string The cluster node name.\nguest integer Only list replication jobs for this guest." + }, + { + "id": "GET /nodes/{node}/replication/{id}", + "method": "GET", + "path": "/nodes/{node}/replication/{id}", + "section": "nodes", + "summary": "index", + "description": "Directory index.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/replication/{id}\nnodes\nindex\nDirectory index.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/replication/{id}/log", + "method": "GET", + "path": "/nodes/{node}/replication/{id}/log", + "section": "nodes", + "summary": "read_job_log", + "description": "Read replication job log.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "limit", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "start", + "type": "integer", + "required": false, + "minimum": 0 + } + ], + "returns": { + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "description": "Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/replication/{id}/log\nnodes\nread_job_log\nRead replication job log.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name.\nlimit integer\nstart integer" + }, + { + "id": "POST /nodes/{node}/replication/{id}/schedule_now", + "method": "POST", + "path": "/nodes/{node}/replication/{id}/schedule_now", + "section": "nodes", + "summary": "schedule_now", + "description": "Schedule replication job to start as soon as possible.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/replication/{id}/schedule_now\nnodes\nschedule_now\nSchedule replication job to start as soon as possible.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/replication/{id}/status", + "method": "GET", + "path": "/nodes/{node}/replication/{id}/status", + "section": "nodes", + "summary": "job_status", + "description": "Get replication job status.", + "pathParameters": [ + { + "name": "id", + "type": "string", + "required": true, + "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" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/replication/{id}/status\nnodes\njob_status\nGet replication job status.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/report", + "method": "GET", + "path": "/nodes/{node}/report", + "section": "nodes", + "summary": "report", + "description": "Gather various systems information about a node", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/report\nnodes\nreport\nGather various systems information about a node\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/rrd", + "method": "GET", + "path": "/nodes/{node}/rrd", + "section": "nodes", + "summary": "rrd", + "description": "Read node RRD statistics (returns PNG)", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "ds", + "type": "string", + "required": true, + "description": "The list of datasources you want to display.", + "format": "pve-configid-list" + }, + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year", + "decade" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/rrd\nnodes\nrrd\nRead node RRD statistics (returns PNG)\nnode string The cluster node name.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year decade\ncf string The RRD consolidation function AVERAGE MAX" + }, + { + "id": "GET /nodes/{node}/rrddata", + "method": "GET", + "path": "/nodes/{node}/rrddata", + "section": "nodes", + "summary": "rrddata", + "description": "Read node RRD statistics", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year", + "decade" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/rrddata\nnodes\nrrddata\nRead node RRD statistics\nnode string The cluster node name.\ntimeframe string Specify the time frame you are interested in. hour day week month year decade\ncf string The RRD consolidation function AVERAGE MAX" + }, + { + "id": "GET /nodes/{node}/scan", + "method": "GET", + "path": "/nodes/{node}/scan", + "section": "nodes", + "summary": "index", + "description": "Index of available scan methods", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "method": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{method}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan\nnodes\nindex\nIndex of available scan methods\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/scan/cifs", + "method": "GET", + "path": "/nodes/{node}/scan/cifs", + "section": "nodes", + "summary": "cifsscan", + "description": "Scan remote CIFS server.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "server", + "type": "string", + "required": true, + "description": "The server address (name or IP).", + "format": "pve-storage-server" + }, + { + "name": "domain", + "type": "string", + "required": false, + "description": "SMB domain (Workgroup)." + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "User password." + }, + { + "name": "username", + "type": "string", + "required": false, + "description": "User name." + } + ], + "returns": { + "items": { + "properties": { + "description": { + "description": "Descriptive text from server.", + "type": "string" + }, + "share": { + "description": "The cifs share name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan/cifs\nnodes\ncifsscan\nScan remote CIFS server.\nnode string The cluster node name.\nserver string The server address (name or IP).\ndomain string SMB domain (Workgroup).\npassword string User password.\nusername string User name." + }, + { + "id": "GET /nodes/{node}/scan/iscsi", + "method": "GET", + "path": "/nodes/{node}/scan/iscsi", + "section": "nodes", + "summary": "iscsiscan", + "description": "Scan remote iSCSI server.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "portal", + "type": "string", + "required": true, + "description": "The iSCSI portal (IP or DNS name with optional port).", + "format": "pve-storage-portal-dns" + } + ], + "returns": { + "items": { + "properties": { + "portal": { + "description": "The iSCSI portal name.", + "type": "string" + }, + "target": { + "description": "The iSCSI target name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan/iscsi\nnodes\niscsiscan\nScan remote iSCSI server.\nnode string The cluster node name.\nportal string The iSCSI portal (IP or DNS name with optional port)." + }, + { + "id": "GET /nodes/{node}/scan/lvm", + "method": "GET", + "path": "/nodes/{node}/scan/lvm", + "section": "nodes", + "summary": "lvmscan", + "description": "List local LVM volume groups.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "vg": { + "description": "The LVM logical volume group name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan/lvm\nnodes\nlvmscan\nList local LVM volume groups.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/scan/lvmthin", + "method": "GET", + "path": "/nodes/{node}/scan/lvmthin", + "section": "nodes", + "summary": "lvmthinscan", + "description": "List local LVM Thin Pools.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "vg", + "type": "string", + "required": true + } + ], + "returns": { + "items": { + "properties": { + "lv": { + "description": "The LVM Thin Pool name (LVM logical volume).", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan/lvmthin\nnodes\nlvmthinscan\nList local LVM Thin Pools.\nnode string The cluster node name.\nvg string" + }, + { + "id": "GET /nodes/{node}/scan/nfs", + "method": "GET", + "path": "/nodes/{node}/scan/nfs", + "section": "nodes", + "summary": "nfsscan", + "description": "Scan remote NFS server.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "server", + "type": "string", + "required": true, + "description": "The server address (name or IP).", + "format": "pve-storage-server" + } + ], + "returns": { + "items": { + "properties": { + "options": { + "description": "NFS export options.", + "type": "string" + }, + "path": { + "description": "The exported path.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan/nfs\nnodes\nnfsscan\nScan remote NFS server.\nnode string The cluster node name.\nserver string The server address (name or IP)." + }, + { + "id": "GET /nodes/{node}/scan/pbs", + "method": "GET", + "path": "/nodes/{node}/scan/pbs", + "section": "nodes", + "summary": "pbsscan", + "description": "Scan remote Proxmox Backup Server.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "password", + "type": "string", + "required": true, + "description": "User password or API token secret." + }, + { + "name": "server", + "type": "string", + "required": true, + "description": "The server address (name or IP).", + "format": "pve-storage-server" + }, + { + "name": "username", + "type": "string", + "required": true, + "description": "User-name or API token-ID." + }, + { + "name": "fingerprint", + "type": "string", + "required": false, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "port", + "type": "integer", + "required": false, + "description": "Optional port.", + "default": 8007, + "minimum": 1, + "maximum": 65535 + } + ], + "returns": { + "items": { + "properties": { + "comment": { + "description": "Comment from server.", + "optional": 1, + "type": "string" + }, + "store": { + "description": "The datastore name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan/pbs\nnodes\npbsscan\nScan remote Proxmox Backup Server.\nnode string The cluster node name.\npassword string User password or API token secret.\nserver string The server address (name or IP).\nusername string User-name or API token-ID.\nfingerprint string Certificate SHA 256 fingerprint.\nport integer Optional port." + }, + { + "id": "GET /nodes/{node}/scan/zfs", + "method": "GET", + "path": "/nodes/{node}/scan/zfs", + "section": "nodes", + "summary": "zfsscan", + "description": "Scan zfs pool list on local node.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "pool": { + "description": "ZFS pool name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/scan/zfs\nnodes\nzfsscan\nScan zfs pool list on local node.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn", + "method": "GET", + "path": "/nodes/{node}/sdn", + "section": "nodes", + "summary": "sdnindex", + "description": "SDN index.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn\nnodes\nsdnindex\nSDN index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}", + "section": "nodes", + "summary": "diridx", + "description": "Directory index for SDN fabric status.", + "pathParameters": [ + { + "name": "fabric", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}\nnodes\ndiridx\nDirectory index for SDN fabric status.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}/interfaces", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}/interfaces", + "section": "nodes", + "summary": "interfaces", + "description": "Get all interfaces for a fabric.", + "pathParameters": [ + { + "name": "fabric", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}/interfaces\nnodes\ninterfaces\nGet all interfaces for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}/neighbors", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}/neighbors", + "section": "nodes", + "summary": "neighbors", + "description": "Get all neighbors for a fabric.", + "pathParameters": [ + { + "name": "fabric", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}/neighbors\nnodes\nneighbors\nGet all neighbors for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}/routes", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}/routes", + "section": "nodes", + "summary": "routes", + "description": "Get all routes for a fabric.", + "pathParameters": [ + { + "name": "fabric", + "type": "string", + "required": true, + "description": "Identifier for SDN fabrics", + "format": "pve-sdn-fabric-id" + }, + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}/routes\nnodes\nroutes\nGet all routes for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/vnets/{vnet}", + "method": "GET", + "path": "/nodes/{node}/sdn/vnets/{vnet}", + "section": "nodes", + "summary": "diridx", + "description": "diridx", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "description": "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/vnets/{vnet}\nnodes\ndiridx\ndiridx\nnode string The cluster node name.\nvnet string The SDN vnet object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/vnets/{vnet}/mac-vrf", + "method": "GET", + "path": "/nodes/{node}/sdn/vnets/{vnet}/mac-vrf", + "section": "nodes", + "summary": "mac-vrf", + "description": "Get the MAC VRF for a VNet in an EVPN zone.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "vnet", + "type": "string", + "required": true, + "description": "The SDN vnet object identifier." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/vnets/{vnet}/mac-vrf\nnodes\nmac-vrf\nGet the MAC VRF for a VNet in an EVPN zone.\nnode string The cluster node name.\nvnet string The SDN vnet object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/zones", + "method": "GET", + "path": "/nodes/{node}/sdn/zones", + "section": "nodes", + "summary": "index", + "description": "Get status for all zones.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "Only list entries where you have 'SDN.Audit'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/zones\nnodes\nindex\nGet status for all zones.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}", + "section": "nodes", + "summary": "diridx", + "description": "Directory index for SDN zone status.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}\nnodes\ndiridx\nDirectory index for SDN zone status.\nnode string The cluster node name.\nzone string The SDN zone object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}/bridges", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}/bridges", + "section": "nodes", + "summary": "bridges", + "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.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "zone name or \"localnetwork\"" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}/bridges\nnodes\nbridges\nGet a list of all bridges (vnets) that are part of a zone, as well as the ports that are members of that bridge.\nnode string The cluster node name.\nzone string zone name or \"localnetwork\"" + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}/content", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}/content", + "section": "nodes", + "summary": "index", + "description": "List zone content.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "The SDN zone object identifier." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}/content\nnodes\nindex\nList zone content.\nnode string The cluster node name.\nzone string The SDN zone object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}/ip-vrf", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}/ip-vrf", + "section": "nodes", + "summary": "ip-vrf", + "description": "Get the IP VRF of an EVPN zone.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "zone", + "type": "string", + "required": true, + "description": "Name of an EVPN zone." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}/ip-vrf\nnodes\nip-vrf\nGet the IP VRF of an EVPN zone.\nnode string The cluster node name.\nzone string Name of an EVPN zone." + }, + { + "id": "GET /nodes/{node}/services", + "method": "GET", + "path": "/nodes/{node}/services", + "section": "nodes", + "summary": "index", + "description": "Service list.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/services\nnodes\nindex\nService list.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/services/{service}", + "method": "GET", + "path": "/nodes/{node}/services/{service}", + "section": "nodes", + "summary": "srvcmdidx", + "description": "Directory index", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "service", + "type": "string", + "required": true, + "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" + ] + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/services/{service}\nnodes\nsrvcmdidx\nDirectory index\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/reload", + "method": "POST", + "path": "/nodes/{node}/services/{service}/reload", + "section": "nodes", + "summary": "service_reload", + "description": "Reload service. Falls back to restart if service cannot be reloaded.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "service", + "type": "string", + "required": true, + "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" + ] + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/services/{service}/reload\nnodes\nservice_reload\nReload service. Falls back to restart if service cannot be reloaded.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/restart", + "method": "POST", + "path": "/nodes/{node}/services/{service}/restart", + "section": "nodes", + "summary": "service_restart", + "description": "Hard restart service. Use reload if you want to reduce interruptions.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "service", + "type": "string", + "required": true, + "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" + ] + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/services/{service}/restart\nnodes\nservice_restart\nHard restart service. Use reload if you want to reduce interruptions.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/start", + "method": "POST", + "path": "/nodes/{node}/services/{service}/start", + "section": "nodes", + "summary": "service_start", + "description": "Start service.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "service", + "type": "string", + "required": true, + "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" + ] + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/services/{service}/start\nnodes\nservice_start\nStart service.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "GET /nodes/{node}/services/{service}/state", + "method": "GET", + "path": "/nodes/{node}/services/{service}/state", + "section": "nodes", + "summary": "service_state", + "description": "Read service properties", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "service", + "type": "string", + "required": true, + "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" + ] + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/services/{service}/state\nnodes\nservice_state\nRead service properties\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/stop", + "method": "POST", + "path": "/nodes/{node}/services/{service}/stop", + "section": "nodes", + "summary": "service_stop", + "description": "Stop service.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "service", + "type": "string", + "required": true, + "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" + ] + } + ], + "requestParameters": [], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/services/{service}/stop\nnodes\nservice_stop\nStop service.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/spiceshell", + "method": "POST", + "path": "/nodes/{node}/spiceshell", + "section": "nodes", + "summary": "spiceshell", + "description": "Creates a SPICE shell.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "cmd", + "type": "string", + "required": false, + "description": "Run specific command or default to login (requires 'root@pam')", + "enum": [ + "ceph_install", + "login", + "upgrade" + ], + "default": "login" + }, + { + "name": "cmd-opts", + "type": "string", + "required": false, + "description": "Add parameters to a command. Encoded as null terminated strings.", + "default": "" + }, + { + "name": "proxy", + "type": "string", + "required": false, + "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" + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/spiceshell\nnodes\nspiceshell\nCreates a SPICE shell.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings.\nproxy string 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)." + }, + { + "id": "POST /nodes/{node}/startall", + "method": "POST", + "path": "/nodes/{node}/startall", + "section": "nodes", + "summary": "startall", + "description": "Start all VMs and containers located on this node (by default only those with onboot=1).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Issue start command even if virtual guest have 'onboot' not set or set to off.", + "default": "off" + }, + { + "name": "max-workers", + "type": "integer", + "required": false, + "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.", + "minimum": 1, + "maximum": 64 + }, + { + "name": "vms", + "type": "string", + "required": false, + "description": "Only consider guests from this comma separated list of VMIDs.", + "format": "pve-vmid-list" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/startall\nnodes\nstartall\nStart all VMs and containers located on this node (by default only those with onboot=1).\nnode string The cluster node name.\nforce boolean Issue start command even if virtual guest have 'onboot' not set or set to off.\nmax-workers integer 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.\nvms string Only consider guests from this comma separated list of VMIDs." + }, + { + "id": "GET /nodes/{node}/status", + "method": "GET", + "path": "/nodes/{node}/status", + "section": "nodes", + "summary": "status", + "description": "Read node status", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/status\nnodes\nstatus\nRead node status\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/status", + "method": "POST", + "path": "/nodes/{node}/status", + "section": "nodes", + "summary": "node_cmd", + "description": "Reboot or shutdown a node.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "command", + "type": "string", + "required": true, + "description": "Specify the command.", + "enum": [ + "reboot", + "shutdown" + ] + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/status\nnodes\nnode_cmd\nReboot or shutdown a node.\nnode string The cluster node name.\ncommand string Specify the command. reboot shutdown" + }, + { + "id": "POST /nodes/{node}/stopall", + "method": "POST", + "path": "/nodes/{node}/stopall", + "section": "nodes", + "summary": "stopall", + "description": "Stop all VMs and Containers.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "force-stop", + "type": "boolean", + "required": false, + "description": "Force a hard-stop after the timeout.", + "default": 1 + }, + { + "name": "max-workers", + "type": "integer", + "required": false, + "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.", + "minimum": 1, + "maximum": 64 + }, + { + "name": "timeout", + "type": "integer", + "required": false, + "description": "Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.", + "default": 180, + "minimum": 0, + "maximum": 7200 + }, + { + "name": "vms", + "type": "string", + "required": false, + "description": "Only consider Guests with these IDs.", + "format": "pve-vmid-list" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/stopall\nnodes\nstopall\nStop all VMs and Containers.\nnode string The cluster node name.\nforce-stop boolean Force a hard-stop after the timeout.\nmax-workers integer 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.\ntimeout integer Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.\nvms string Only consider Guests with these IDs." + }, + { + "id": "GET /nodes/{node}/storage", + "method": "GET", + "path": "/nodes/{node}/storage", + "section": "nodes", + "summary": "index", + "description": "Get status for all datastores.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "content", + "type": "string", + "required": false, + "description": "Only list stores which support this content type.", + "format": "pve-storage-content-list" + }, + { + "name": "enabled", + "type": "boolean", + "required": false, + "description": "Only list stores which are enabled (not disabled in config).", + "default": 0 + }, + { + "name": "format", + "type": "boolean", + "required": false, + "description": "Include information about formats", + "default": 0 + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Only list status for specified storage", + "format": "pve-storage-id" + }, + { + "name": "target", + "type": "string", + "required": false, + "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" + } + ], + "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" + }, + "permissions": { + "description": "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage\nnodes\nindex\nGet status for all datastores.\nnode string The cluster node name.\ncontent string Only list stores which support this content type.\nenabled boolean Only list stores which are enabled (not disabled in config).\nformat boolean Include information about formats\nstorage string Only list status for specified storage\ntarget string If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}", + "section": "nodes", + "summary": "diridx", + "description": "diridx", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}\nnodes\ndiridx\ndiridx\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/content", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/content", + "section": "nodes", + "summary": "index", + "description": "List storage content.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "content", + "type": "string", + "required": false, + "description": "Only list content of this type.", + "format": "pve-storage-content" + }, + { + "name": "vmid", + "type": "integer", + "required": false, + "description": "Only list images for this VM", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/content\nnodes\nindex\nList storage content.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Only list content of this type.\nvmid integer Only list images for this VM\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/content", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/content", + "section": "nodes", + "summary": "create", + "description": "Allocate disk images.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "filename", + "type": "string", + "required": true, + "description": "The name of the file to create." + }, + { + "name": "size", + "type": "string", + "required": true, + "description": "Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)" + }, + { + "name": "vmid", + "type": "integer", + "required": true, + "description": "Specify owner VM", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + }, + { + "name": "format", + "type": "string", + "required": false, + "description": "Format of the image.", + "enum": [ + "raw", + "qcow2", + "subvol", + "vmdk" + ] + } + ], + "returns": { + "description": "Volume identifier", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/storage/{storage}/content\nnodes\ncreate\nAllocate disk images.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilename string The name of the file to create.\nsize string Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)\nvmid integer Specify owner VM\nformat string Format of the image. raw qcow2 subvol vmdk\ndatastore\nvolume storage" + }, + { + "id": "DELETE /nodes/{node}/storage/{storage}/content/{volume}", + "method": "DELETE", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "delete", + "description": "Delete volume", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "volume", + "type": "string", + "required": true, + "description": "Volume identifier" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "delay", + "type": "integer", + "required": false, + "description": "Time to wait for the task to finish. We return 'null' if the task finish within that time.", + "minimum": 1, + "maximum": 30 + } + ], + "returns": { + "optional": 1, + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ndelete\nDelete volume\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\ndelay integer Time to wait for the task to finish. We return 'null' if the task finish within that time.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/content/{volume}", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "info", + "description": "Get volume attributes", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "volume", + "type": "string", + "required": true, + "description": "Volume identifier" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "You need read access for the volume.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ninfo\nGet volume attributes\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/content/{volume}", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "copy", + "description": "Copy a volume. This is experimental code - do not use.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "volume", + "type": "string", + "required": true, + "description": "Source volume identifier" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "target", + "type": "string", + "required": true, + "description": "Target volume identifier" + }, + { + "name": "target_node", + "type": "string", + "required": false, + "description": "Target node. Default is local node.", + "format": "pve-node" + } + ], + "returns": { + "type": "string" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ncopy\nCopy a volume. This is experimental code - do not use.\nnode string The cluster node name.\nvolume string Source volume identifier\nstorage string The storage identifier.\ntarget string Target volume identifier\ntarget_node string Target node. Default is local node.\ndatastore\nvolume storage" + }, + { + "id": "PUT /nodes/{node}/storage/{storage}/content/{volume}", + "method": "PUT", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "updateattributes", + "description": "Update volume attributes", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "volume", + "type": "string", + "required": true, + "description": "Volume identifier" + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "notes", + "type": "string", + "required": false, + "description": "The new notes." + }, + { + "name": "protected", + "type": "boolean", + "required": false, + "description": "Protection status. Currently only supported for backups." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "description": "You need read access for the volume.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\nupdateattributes\nUpdate volume attributes\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\nnotes string The new notes.\nprotected boolean Protection status. Currently only supported for backups.\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/download-url", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/download-url", + "section": "nodes", + "summary": "download_url", + "description": "Download templates, ISO images, OVAs and VM images by using an URL.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "content", + "type": "string", + "required": true, + "description": "Content type.", + "enum": [ + "iso", + "vztmpl", + "import" + ], + "format": "pve-storage-content" + }, + { + "name": "filename", + "type": "string", + "required": true, + "description": "The name of the file to create. Caution: This will be normalized!" + }, + { + "name": "url", + "type": "string", + "required": true, + "description": "The URL to download the file from." + }, + { + "name": "checksum", + "type": "string", + "required": false, + "description": "The expected checksum of the file." + }, + { + "name": "checksum-algorithm", + "type": "string", + "required": false, + "description": "The algorithm to calculate the checksum of the file.", + "enum": [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ] + }, + { + "name": "compression", + "type": "string", + "required": false, + "description": "Decompress the downloaded file using the specified compression algorithm." + }, + { + "name": "verify-certificates", + "type": "boolean", + "required": false, + "description": "If false, no SSL/TLS certificates will be verified.", + "default": 1 + } + ], + "returns": { + "type": "string" + }, + "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." + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/storage/{storage}/download-url\nnodes\ndownload_url\nDownload templates, ISO images, OVAs and VM images by using an URL.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Content type. iso vztmpl import\nfilename string The name of the file to create. Caution: This will be normalized!\nurl string The URL to download the file from.\nchecksum string The expected checksum of the file.\nchecksum-algorithm string The algorithm to calculate the checksum of the file. md5 sha1 sha224 sha256 sha384 sha512\ncompression string Decompress the downloaded file using the specified compression algorithm.\nverify-certificates boolean If false, no SSL/TLS certificates will be verified.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/file-restore/download", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/file-restore/download", + "section": "nodes", + "summary": "download", + "description": "Extract a file or directory (as zip archive) from a PBS backup.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "filepath", + "type": "string", + "required": true, + "description": "base64-path to the directory or file to download." + }, + { + "name": "volume", + "type": "string", + "required": true, + "description": "Backup volume ID or name. Currently only PBS snapshots are supported." + }, + { + "name": "tar", + "type": "boolean", + "required": false, + "description": "Download dirs as 'tar.zst' instead of 'zip'.", + "default": 0 + } + ], + "returns": { + "type": "any" + }, + "permissions": { + "description": "You need read access for the volume.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/file-restore/download\nnodes\ndownload\nExtract a file or directory (as zip archive) from a PBS backup.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilepath string base64-path to the directory or file to download.\nvolume string Backup volume ID or name. Currently only PBS snapshots are supported.\ntar boolean Download dirs as 'tar.zst' instead of 'zip'.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/file-restore/list", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/file-restore/list", + "section": "nodes", + "summary": "list", + "description": "List files and directories for single file restore under the given path.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "filepath", + "type": "string", + "required": true, + "description": "base64-path to the directory or file being listed, or \"/\"." + }, + { + "name": "volume", + "type": "string", + "required": true, + "description": "Backup volume ID or name. Currently only PBS snapshots are supported." + } + ], + "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" + }, + "permissions": { + "description": "You need read access for the volume.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/file-restore/list\nnodes\nlist\nList files and directories for single file restore under the given path.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilepath string base64-path to the directory or file being listed, or \"/\".\nvolume string Backup volume ID or name. Currently only PBS snapshots are supported.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/identity", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/identity", + "section": "nodes", + "summary": "identity", + "description": "Return identity information for this storage instance.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/identity\nnodes\nidentity\nReturn identity information for this storage instance.\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/import-metadata", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/import-metadata", + "section": "nodes", + "summary": "get_import_metadata", + "description": "Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "volume", + "type": "string", + "required": true, + "description": "Volume identifier for the guest archive/entry." + } + ], + "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" + }, + "permissions": { + "description": "You need read access for the volume.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/import-metadata\nnodes\nget_import_metadata\nGet the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM\nnode string The cluster node name.\nstorage string The storage identifier.\nvolume string Volume identifier for the guest archive/entry.\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/oci-registry-pull", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/oci-registry-pull", + "section": "nodes", + "summary": "oci_registry_pull", + "description": "Pull an OCI image from a registry.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "reference", + "type": "string", + "required": true, + "description": "The reference to the OCI image to download." + }, + { + "name": "filename", + "type": "string", + "required": false, + "description": "Custom destination file name of the OCI image. Caution: This will be normalized!" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "and", + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/storage/{storage}/oci-registry-pull\nnodes\noci_registry_pull\nPull an OCI image from a registry.\nnode string The cluster node name.\nstorage string The storage identifier.\nreference string The reference to the OCI image to download.\nfilename string Custom destination file name of the OCI image. Caution: This will be normalized!\ndatastore\nvolume storage" + }, + { + "id": "DELETE /nodes/{node}/storage/{storage}/prunebackups", + "method": "DELETE", + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "section": "nodes", + "summary": "delete", + "description": "Prune backups. Only those using the standard naming scheme are considered.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "prune-backups", + "type": "string", + "required": false, + "description": "Use these retention options instead of those from the storage configuration.", + "format": "prune-backups" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum": [ + "qemu", + "lxc" + ] + }, + { + "name": "vmid", + "type": "integer", + "required": false, + "description": "Only prune backups for this VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "returns": { + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/storage/{storage}/prunebackups\nnodes\ndelete\nPrune backups. Only those using the standard naming scheme are considered.\nnode string The cluster node name.\nstorage string The storage identifier.\nprune-backups string Use these retention options instead of those from the storage configuration.\ntype string Either 'qemu' or 'lxc'. Only consider backups for guests of this type. qemu lxc\nvmid integer Only prune backups for this VM.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/prunebackups", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "section": "nodes", + "summary": "dryrun", + "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.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "prune-backups", + "type": "string", + "required": false, + "description": "Use these retention options instead of those from the storage configuration.", + "format": "prune-backups" + }, + { + "name": "type", + "type": "string", + "required": false, + "description": "Either 'qemu' or 'lxc'. Only consider backups for guests of this type.", + "enum": [ + "qemu", + "lxc" + ] + }, + { + "name": "vmid", + "type": "integer", + "required": false, + "description": "Only consider backups for this guest.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/prunebackups\nnodes\ndryrun\nGet 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.\nnode string The cluster node name.\nstorage string The storage identifier.\nprune-backups string Use these retention options instead of those from the storage configuration.\ntype string Either 'qemu' or 'lxc'. Only consider backups for guests of this type. qemu lxc\nvmid integer Only consider backups for this guest.\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/rrd", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/rrd", + "section": "nodes", + "summary": "rrd", + "description": "Read storage RRD statistics (returns PNG).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "ds", + "type": "string", + "required": true, + "description": "The list of datasources you want to display.", + "format": "pve-configid-list" + }, + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/rrd\nnodes\nrrd\nRead storage RRD statistics (returns PNG).\nnode string The cluster node name.\nstorage string The storage identifier.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/rrddata", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/rrddata", + "section": "nodes", + "summary": "rrddata", + "description": "Read storage RRD statistics.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "timeframe", + "type": "string", + "required": true, + "description": "Specify the time frame you are interested in.", + "enum": [ + "hour", + "day", + "week", + "month", + "year" + ] + }, + { + "name": "cf", + "type": "string", + "required": false, + "description": "The RRD consolidation function", + "enum": [ + "AVERAGE", + "MAX" + ] + } + ], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/rrddata\nnodes\nrrddata\nRead storage RRD statistics.\nnode string The cluster node name.\nstorage string The storage identifier.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/status", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/status", + "section": "nodes", + "summary": "read_status", + "description": "Read storage status.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/storage/{storage}/status\nnodes\nread_status\nRead storage status.\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/upload", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/upload", + "section": "nodes", + "summary": "upload", + "description": "Upload templates, ISO images, OVAs and VM images.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "content", + "type": "string", + "required": true, + "description": "Content type.", + "enum": [ + "iso", + "vztmpl", + "import" + ], + "format": "pve-storage-content" + }, + { + "name": "filename", + "type": "string", + "required": true, + "description": "The name of the file to create. Caution: This will be normalized!" + }, + { + "name": "checksum", + "type": "string", + "required": false, + "description": "The expected checksum of the file." + }, + { + "name": "checksum-algorithm", + "type": "string", + "required": false, + "description": "The algorithm to calculate the checksum of the file.", + "enum": [ + "md5", + "sha1", + "sha224", + "sha256", + "sha384", + "sha512" + ] + }, + { + "name": "tmpfilename", + "type": "string", + "required": false, + "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." + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/storage/{storage}/upload\nnodes\nupload\nUpload templates, ISO images, OVAs and VM images.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Content type. iso vztmpl import\nfilename string The name of the file to create. Caution: This will be normalized!\nchecksum string The expected checksum of the file.\nchecksum-algorithm string The algorithm to calculate the checksum of the file. md5 sha1 sha224 sha256 sha384 sha512\ntmpfilename string 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.\ndatastore\nvolume storage" + }, + { + "id": "DELETE /nodes/{node}/subscription", + "method": "DELETE", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "delete", + "description": "Delete subscription key of this node.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/subscription\nnodes\ndelete\nDelete subscription key of this node.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/subscription", + "method": "GET", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "get", + "description": "Read subscription info.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/subscription\nnodes\nget\nRead subscription info.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/subscription", + "method": "POST", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "update", + "description": "Update subscription info.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "force", + "type": "boolean", + "required": false, + "description": "Always connect to server, even if local cache is still valid.", + "default": 0 + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/subscription\nnodes\nupdate\nUpdate subscription info.\nnode string The cluster node name.\nforce boolean Always connect to server, even if local cache is still valid." + }, + { + "id": "PUT /nodes/{node}/subscription", + "method": "PUT", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "set", + "description": "Set subscription key.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "key", + "type": "string", + "required": true, + "description": "Proxmox VE subscription key" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/subscription\nnodes\nset\nSet subscription key.\nnode string The cluster node name.\nkey string Proxmox VE subscription key" + }, + { + "id": "POST /nodes/{node}/suspendall", + "method": "POST", + "path": "/nodes/{node}/suspendall", + "section": "nodes", + "summary": "suspendall", + "description": "Suspend all VMs.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "max-workers", + "type": "integer", + "required": false, + "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.", + "minimum": 1, + "maximum": 64 + }, + { + "name": "vms", + "type": "string", + "required": false, + "description": "Only consider Guests with these IDs.", + "format": "pve-vmid-list" + } + ], + "returns": { + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/suspendall\nnodes\nsuspendall\nSuspend all VMs.\nnode string The cluster node name.\nmax-workers integer 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.\nvms string Only consider Guests with these IDs." + }, + { + "id": "GET /nodes/{node}/syslog", + "method": "GET", + "path": "/nodes/{node}/syslog", + "section": "nodes", + "summary": "syslog", + "description": "Read system log", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "limit", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "service", + "type": "string", + "required": false, + "description": "Service ID" + }, + { + "name": "since", + "type": "string", + "required": false, + "description": "Display all log since this date-time string." + }, + { + "name": "start", + "type": "integer", + "required": false, + "minimum": 0 + }, + { + "name": "until", + "type": "string", + "required": false, + "description": "Display all log until this date-time string." + } + ], + "returns": { + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/syslog\nnodes\nsyslog\nRead system log\nnode string The cluster node name.\nlimit integer\nservice string Service ID\nsince string Display all log since this date-time string.\nstart integer\nuntil string Display all log until this date-time string." + }, + { + "id": "GET /nodes/{node}/tasks", + "method": "GET", + "path": "/nodes/{node}/tasks", + "section": "nodes", + "summary": "node_tasks", + "description": "Read task list for one node (finished tasks).", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "errors", + "type": "boolean", + "required": false, + "description": "Only list tasks with a status of ERROR.", + "default": 0 + }, + { + "name": "limit", + "type": "integer", + "required": false, + "description": "Only list this number of tasks.", + "default": 50, + "minimum": 0 + }, + { + "name": "since", + "type": "integer", + "required": false, + "description": "Only list tasks since this UNIX epoch." + }, + { + "name": "source", + "type": "string", + "required": false, + "description": "List archived, active or all tasks.", + "enum": [ + "archive", + "active", + "all" + ], + "default": "archive" + }, + { + "name": "start", + "type": "integer", + "required": false, + "description": "List tasks beginning from this offset.", + "default": 0, + "minimum": 0 + }, + { + "name": "statusfilter", + "type": "string", + "required": false, + "description": "List of Task States that should be returned.", + "format": "pve-task-status-type-list" + }, + { + "name": "typefilter", + "type": "string", + "required": false, + "description": "Only list tasks of this type (e.g., vzstart, vzdump)." + }, + { + "name": "until", + "type": "integer", + "required": false, + "description": "Only list tasks until this UNIX epoch." + }, + { + "name": "userfilter", + "type": "string", + "required": false, + "description": "Only list tasks from this user." + }, + { + "name": "vmid", + "type": "integer", + "required": false, + "description": "Only list tasks for this VM.", + "minimum": 100, + "maximum": 999999999, + "format": "pve-vmid" + } + ], + "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" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/tasks\nnodes\nnode_tasks\nRead task list for one node (finished tasks).\nnode string The cluster node name.\nerrors boolean Only list tasks with a status of ERROR.\nlimit integer Only list this number of tasks.\nsince integer Only list tasks since this UNIX epoch.\nsource string List archived, active or all tasks. archive active all\nstart integer List tasks beginning from this offset.\nstatusfilter string List of Task States that should be returned.\ntypefilter string Only list tasks of this type (e.g., vzstart, vzdump).\nuntil integer Only list tasks until this UNIX epoch.\nuserfilter string Only list tasks from this user.\nvmid integer Only list tasks for this VM." + }, + { + "id": "DELETE /nodes/{node}/tasks/{upid}", + "method": "DELETE", + "path": "/nodes/{node}/tasks/{upid}", + "section": "nodes", + "summary": "stop_task", + "description": "Stop a task.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "upid", + "type": "string", + "required": true + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "description": "The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/nodes/{node}/tasks/{upid}\nnodes\nstop_task\nStop a task.\nnode string The cluster node name.\nupid string" + }, + { + "id": "GET /nodes/{node}/tasks/{upid}", + "method": "GET", + "path": "/nodes/{node}/tasks/{upid}", + "section": "nodes", + "summary": "upid_index", + "description": "upid_index", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "upid", + "type": "string", + "required": true + } + ], + "requestParameters": [], + "returns": { + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/tasks/{upid}\nnodes\nupid_index\nupid_index\nnode string The cluster node name.\nupid string" + }, + { + "id": "GET /nodes/{node}/tasks/{upid}/log", + "method": "GET", + "path": "/nodes/{node}/tasks/{upid}/log", + "section": "nodes", + "summary": "read_task_log", + "description": "Read task log.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "upid", + "type": "string", + "required": true, + "description": "The task's unique ID." + } + ], + "requestParameters": [ + { + "name": "download", + "type": "boolean", + "required": false, + "description": "Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters" + }, + { + "name": "limit", + "type": "integer", + "required": false, + "description": "The number of lines to read from the tasklog.", + "default": 50, + "minimum": 0 + }, + { + "name": "start", + "type": "integer", + "required": false, + "description": "Start at this line when reading the tasklog", + "default": 0, + "minimum": 0 + } + ], + "returns": { + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "permissions": { + "description": "The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/tasks/{upid}/log\nnodes\nread_task_log\nRead task log.\nnode string The cluster node name.\nupid string The task's unique ID.\ndownload boolean Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters\nlimit integer The number of lines to read from the tasklog.\nstart integer Start at this line when reading the tasklog" + }, + { + "id": "GET /nodes/{node}/tasks/{upid}/status", + "method": "GET", + "path": "/nodes/{node}/tasks/{upid}/status", + "section": "nodes", + "summary": "read_task_status", + "description": "Read task status.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + }, + { + "name": "upid", + "type": "string", + "required": true, + "description": "The task's unique ID." + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "description": "The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/tasks/{upid}/status\nnodes\nread_task_status\nRead task status.\nnode string The cluster node name.\nupid string The task's unique ID." + }, + { + "id": "POST /nodes/{node}/termproxy", + "method": "POST", + "path": "/nodes/{node}/termproxy", + "section": "nodes", + "summary": "termproxy", + "description": "Creates a VNC Shell proxy.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "cmd", + "type": "string", + "required": false, + "description": "Run specific command or default to login (requires 'root@pam')", + "enum": [ + "ceph_install", + "login", + "upgrade" + ], + "default": "login" + }, + { + "name": "cmd-opts", + "type": "string", + "required": false, + "description": "Add parameters to a command. Encoded as null terminated strings.", + "default": "" + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/termproxy\nnodes\ntermproxy\nCreates a VNC Shell proxy.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings." + }, + { + "id": "GET /nodes/{node}/time", + "method": "GET", + "path": "/nodes/{node}/time", + "section": "nodes", + "summary": "time", + "description": "Read server time and time zone settings.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/time\nnodes\ntime\nRead server time and time zone settings.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/time", + "method": "PUT", + "path": "/nodes/{node}/time", + "section": "nodes", + "summary": "set_timezone", + "description": "Set time zone.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "timezone", + "type": "string", + "required": true, + "description": "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names." + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/nodes/{node}/time\nnodes\nset_timezone\nSet time zone.\nnode string The cluster node name.\ntimezone string Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names." + }, + { + "id": "GET /nodes/{node}/version", + "method": "GET", + "path": "/nodes/{node}/version", + "section": "nodes", + "summary": "version", + "description": "API version details", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/version\nnodes\nversion\nAPI version details\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/vncshell", + "method": "POST", + "path": "/nodes/{node}/vncshell", + "section": "nodes", + "summary": "vncshell", + "description": "Creates a VNC Shell proxy.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "cmd", + "type": "string", + "required": false, + "description": "Run specific command or default to login (requires 'root@pam')", + "enum": [ + "ceph_install", + "login", + "upgrade" + ], + "default": "login" + }, + { + "name": "cmd-opts", + "type": "string", + "required": false, + "description": "Add parameters to a command. Encoded as null terminated strings.", + "default": "" + }, + { + "name": "height", + "type": "integer", + "required": false, + "description": "sets the height of the console in pixels.", + "minimum": 16, + "maximum": 2160 + }, + { + "name": "websocket", + "type": "boolean", + "required": false, + "description": "use websocket instead of standard vnc." + }, + { + "name": "width", + "type": "integer", + "required": false, + "description": "sets the width of the console in pixels.", + "minimum": 16, + "maximum": 4096 + } + ], + "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" + } + } + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] + }, + "raw": { + "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" + } + } + } + }, + "searchText": "POST\n/nodes/{node}/vncshell\nnodes\nvncshell\nCreates a VNC Shell proxy.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings.\nheight integer sets the height of the console in pixels.\nwebsocket boolean use websocket instead of standard vnc.\nwidth integer sets the width of the console in pixels." + }, + { + "id": "GET /nodes/{node}/vncwebsocket", + "method": "GET", + "path": "/nodes/{node}/vncwebsocket", + "section": "nodes", + "summary": "vncwebsocket", + "description": "Opens a websocket for VNC traffic.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "port", + "type": "integer", + "required": true, + "description": "Port number returned by previous 'vncshell' call.", + "minimum": 5900, + "maximum": 5999 + }, + { + "name": "vncticket", + "type": "string", + "required": true, + "description": "Ticket from previous call to 'vncshell'." + } + ], + "returns": { + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nport integer Port number returned by previous 'vncshell' call.\nvncticket string Ticket from previous call to 'vncshell'." + }, + { + "id": "POST /nodes/{node}/vzdump", + "method": "POST", + "path": "/nodes/{node}/vzdump", + "section": "nodes", + "summary": "vzdump", + "description": "Create backup.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": false, + "description": "Only run if executed on this node.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "all", + "type": "boolean", + "required": false, + "description": "Backup all known guest systems on this host.", + "default": 0 + }, + { + "name": "bwlimit", + "type": "integer", + "required": false, + "description": "Limit I/O bandwidth (in KiB/s).", + "default": 0, + "minimum": 0 + }, + { + "name": "compress", + "type": "string", + "required": false, + "description": "Compress dump file.", + "enum": [ + "0", + "1", + "gzip", + "lzo", + "zstd" + ], + "default": "0" + }, + { + "name": "dumpdir", + "type": "string", + "required": false, + "description": "Store resulting files to specified directory." + }, + { + "name": "exclude", + "type": "string", + "required": false, + "description": "Exclude specified guest systems (assumes --all)", + "format": "pve-vmid-list" + }, + { + "name": "exclude-path", + "type": "array", + "required": false, + "description": "Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory." + }, + { + "name": "fleecing", + "type": "string", + "required": false, + "description": "Options for backup fleecing (VM only).", + "format": "backup-fleecing" + }, + { + "name": "ionice", + "type": "integer", + "required": false, + "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.", + "default": 7, + "minimum": 0, + "maximum": 8 + }, + { + "name": "job-id", + "type": "string", + "required": false, + "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." + }, + { + "name": "lockwait", + "type": "integer", + "required": false, + "description": "Maximal time to wait for the global lock (minutes).", + "default": 180, + "minimum": 0 + }, + { + "name": "mailnotification", + "type": "string", + "required": false, + "description": "Deprecated: use notification targets/matchers instead. Specify when to send a notification mail", + "enum": [ + "always", + "failure" + ], + "default": "always" + }, + { + "name": "mailto", + "type": "string", + "required": false, + "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" + }, + { + "name": "mode", + "type": "string", + "required": false, + "description": "Backup mode.", + "enum": [ + "snapshot", + "suspend", + "stop" + ], + "default": "snapshot" + }, + { + "name": "notes-template", + "type": "string", + "required": false, + "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." + }, + { + "name": "notification-mode", + "type": "string", + "required": false, + "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" + ], + "default": "auto" + }, + { + "name": "pbs-change-detection-mode", + "type": "string", + "required": false, + "description": "PBS mode used to detect file changes and switch encoding format for container backups.", + "enum": [ + "legacy", + "data", + "metadata" + ] + }, + { + "name": "performance", + "type": "string", + "required": false, + "description": "Other performance-related settings.", + "format": "backup-performance" + }, + { + "name": "pigz", + "type": "integer", + "required": false, + "description": "Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.", + "default": 0 + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Backup all known guest systems included in the specified pool." + }, + { + "name": "protected", + "type": "boolean", + "required": false, + "description": "If true, mark backup(s) as protected." + }, + { + "name": "prune-backups", + "type": "string", + "required": false, + "description": "Use these retention options instead of those from the storage configuration.", + "default": "keep-all=1", + "format": "prune-backups" + }, + { + "name": "quiet", + "type": "boolean", + "required": false, + "description": "Be quiet.", + "default": 0 + }, + { + "name": "remove", + "type": "boolean", + "required": false, + "description": "Prune older backups according to 'prune-backups'.", + "default": 1 + }, + { + "name": "script", + "type": "string", + "required": false, + "description": "Use specified hook script." + }, + { + "name": "stdexcludes", + "type": "boolean", + "required": false, + "description": "Exclude temporary files and logs.", + "default": 1 + }, + { + "name": "stdout", + "type": "boolean", + "required": false, + "description": "Write tar to stdout, not to a file." + }, + { + "name": "stop", + "type": "boolean", + "required": false, + "description": "Stop running backup jobs on this host.", + "default": 0 + }, + { + "name": "stopwait", + "type": "integer", + "required": false, + "description": "Maximal time to wait until a guest system is stopped (minutes).", + "default": 10, + "minimum": 0 + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "Store resulting file to this storage.", + "format": "pve-storage-id" + }, + { + "name": "tmpdir", + "type": "string", + "required": false, + "description": "Store temporary files to specified directory." + }, + { + "name": "vmid", + "type": "string", + "required": false, + "description": "The ID of the guest system you want to backup.", + "format": "pve-vmid-list" + }, + { + "name": "zstd", + "type": "integer", + "required": false, + "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.", + "default": 1 + } + ], + "returns": { + "type": "string" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/vzdump\nnodes\nvzdump\nCreate backup.\nnode string Only run if executed on this node.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndumpdir string Store resulting files to specified directory.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nionice integer 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.\njob-id string 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nscript string Use specified hook script.\nstdexcludes boolean Exclude temporary files and logs.\nstdout boolean Write tar to stdout, not to a file.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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." + }, + { + "id": "GET /nodes/{node}/vzdump/defaults", + "method": "GET", + "path": "/nodes/{node}/vzdump/defaults", + "section": "nodes", + "summary": "defaults", + "description": "Get the currently configured vzdump defaults.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "storage", + "type": "string", + "required": false, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "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" + }, + "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" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/vzdump/defaults\nnodes\ndefaults\nGet the currently configured vzdump defaults.\nnode string The cluster node name.\nstorage string The storage identifier." + }, + { + "id": "GET /nodes/{node}/vzdump/extractconfig", + "method": "GET", + "path": "/nodes/{node}/vzdump/extractconfig", + "section": "nodes", + "summary": "extractconfig", + "description": "Extract configuration from vzdump backup archive.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "The cluster node name.", + "format": "pve-node" + } + ], + "requestParameters": [ + { + "name": "volume", + "type": "string", + "required": true, + "description": "Volume identifier" + } + ], + "returns": { + "type": "string" + }, + "permissions": { + "description": "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/nodes/{node}/vzdump/extractconfig\nnodes\nextractconfig\nExtract configuration from vzdump backup archive.\nnode string The cluster node name.\nvolume string Volume identifier" + }, + { + "id": "POST /nodes/{node}/wakeonlan", + "method": "POST", + "path": "/nodes/{node}/wakeonlan", + "section": "nodes", + "summary": "wakeonlan", + "description": "Try to wake a node via 'wake on LAN' network packet.", + "pathParameters": [ + { + "name": "node", + "type": "string", + "required": true, + "description": "target node for wake on LAN packet", + "format": "pve-node" + } + ], + "requestParameters": [], + "returns": { + "description": "MAC address used to assemble the WoL magic packet.", + "format": "mac-addr", + "type": "string" + }, + "permissions": { + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/nodes/{node}/wakeonlan\nnodes\nwakeonlan\nTry to wake a node via 'wake on LAN' network packet.\nnode string target node for wake on LAN packet" + }, + { + "id": "DELETE /pools", + "method": "DELETE", + "path": "/pools", + "section": "pools", + "summary": "delete_pool", + "description": "Delete pool.", + "pathParameters": [], + "requestParameters": [ + { + "name": "poolid", + "type": "string", + "required": true, + "format": "pve-poolid" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You can only delete empty pools (no members)." + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/pools\npools\ndelete_pool\nDelete pool.\npoolid string" + }, + { + "id": "GET /pools", + "method": "GET", + "path": "/pools", + "section": "pools", + "summary": "index", + "description": "List pools or get pool configuration.", + "pathParameters": [], + "requestParameters": [ + { + "name": "poolid", + "type": "string", + "required": false, + "format": "pve-poolid" + }, + { + "name": "type", + "type": "string", + "required": false, + "enum": [ + "qemu", + "lxc", + "storage" + ] + } + ], + "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" + }, + "permissions": { + "description": "List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/pools\npools\nindex\nList pools or get pool configuration.\npoolid string\ntype string qemu lxc storage" + }, + { + "id": "POST /pools", + "method": "POST", + "path": "/pools", + "section": "pools", + "summary": "create_pool", + "description": "Create new pool.", + "pathParameters": [], + "requestParameters": [ + { + "name": "poolid", + "type": "string", + "required": true, + "format": "pve-poolid" + }, + { + "name": "comment", + "type": "string", + "required": false + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/pools\npools\ncreate_pool\nCreate new pool.\npoolid string\ncomment string" + }, + { + "id": "PUT /pools", + "method": "PUT", + "path": "/pools", + "section": "pools", + "summary": "update_pool", + "description": "Update pool.", + "pathParameters": [], + "requestParameters": [ + { + "name": "poolid", + "type": "string", + "required": true, + "format": "pve-poolid" + }, + { + "name": "allow-move", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "delete", + "type": "boolean", + "required": false, + "description": "Remove the passed VMIDs and/or storage IDs instead of adding them.", + "default": 0 + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "List of storage IDs to add or remove from this pool.", + "format": "pve-storage-id-list" + }, + { + "name": "vms", + "type": "string", + "required": false, + "description": "List of guest VMIDs to add or remove from this pool.", + "format": "pve-vmid-list" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You also need the right to modify permissions on any object you add/delete." + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/pools\npools\nupdate_pool\nUpdate pool.\npoolid string\nallow-move boolean Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.\ncomment string\ndelete boolean Remove the passed VMIDs and/or storage IDs instead of adding them.\nstorage string List of storage IDs to add or remove from this pool.\nvms string List of guest VMIDs to add or remove from this pool." + }, + { + "id": "DELETE /pools/{poolid}", + "method": "DELETE", + "path": "/pools/{poolid}", + "section": "pools", + "summary": "delete_pool_deprecated", + "description": "Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').", + "pathParameters": [ + { + "name": "poolid", + "type": "string", + "required": true, + "format": "pve-poolid" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You can only delete empty pools (no members)." + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/pools/{poolid}\npools\ndelete_pool_deprecated\nDelete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').\npoolid string" + }, + { + "id": "GET /pools/{poolid}", + "method": "GET", + "path": "/pools/{poolid}", + "section": "pools", + "summary": "read_pool", + "description": "Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').", + "pathParameters": [ + { + "name": "poolid", + "type": "string", + "required": true, + "format": "pve-poolid" + } + ], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "enum": [ + "qemu", + "lxc", + "storage" + ] + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Audit" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/pools/{poolid}\npools\nread_pool\nGet pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').\npoolid string\ntype string qemu lxc storage" + }, + { + "id": "PUT /pools/{poolid}", + "method": "PUT", + "path": "/pools/{poolid}", + "section": "pools", + "summary": "update_pool_deprecated", + "description": "Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).", + "pathParameters": [ + { + "name": "poolid", + "type": "string", + "required": true, + "format": "pve-poolid" + } + ], + "requestParameters": [ + { + "name": "allow-move", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "comment", + "type": "string", + "required": false + }, + { + "name": "delete", + "type": "boolean", + "required": false, + "description": "Remove the passed VMIDs and/or storage IDs instead of adding them.", + "default": 0 + }, + { + "name": "storage", + "type": "string", + "required": false, + "description": "List of storage IDs to add or remove from this pool.", + "format": "pve-storage-id-list" + }, + { + "name": "vms", + "type": "string", + "required": false, + "description": "List of guest VMIDs to add or remove from this pool.", + "format": "pve-vmid-list" + } + ], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You also need the right to modify permissions on any object you add/delete." + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/pools/{poolid}\npools\nupdate_pool_deprecated\nUpdate pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).\npoolid string\nallow-move boolean Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.\ncomment string\ndelete boolean Remove the passed VMIDs and/or storage IDs instead of adding them.\nstorage string List of storage IDs to add or remove from this pool.\nvms string List of guest VMIDs to add or remove from this pool." + }, + { + "id": "GET /storage", + "method": "GET", + "path": "/storage", + "section": "storage", + "summary": "index", + "description": "Storage index.", + "pathParameters": [], + "requestParameters": [ + { + "name": "type", + "type": "string", + "required": false, + "description": "Only list storage of specific type", + "enum": [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ] + } + ], + "returns": { + "items": { + "properties": { + "storage": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{storage}", + "rel": "child" + } + ], + "type": "array" + }, + "permissions": { + "description": "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/storage\nstorage\nindex\nStorage index.\ntype string Only list storage of specific type btrfs cephfs cifs dir esxi iscsi iscsidirect lvm lvmthin nfs pbs rbd zfs zfspool\ndatastore\nvolume storage" + }, + { + "id": "POST /storage", + "method": "POST", + "path": "/storage", + "section": "storage", + "summary": "create", + "description": "Create a new storage.", + "pathParameters": [], + "requestParameters": [ + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + }, + { + "name": "type", + "type": "string", + "required": true, + "description": "Storage type.", + "enum": [ + "btrfs", + "cephfs", + "cifs", + "dir", + "esxi", + "iscsi", + "iscsidirect", + "lvm", + "lvmthin", + "nfs", + "pbs", + "rbd", + "zfs", + "zfspool" + ] + }, + { + "name": "authsupported", + "type": "string", + "required": false, + "description": "Authsupported." + }, + { + "name": "base", + "type": "string", + "required": false, + "description": "Base volume. This volume is automatically activated.", + "format": "pve-volume-id" + }, + { + "name": "blocksize", + "type": "string", + "required": false, + "description": "ZFS block size", + "format": "pve-storage-zfs-blocksize" + }, + { + "name": "bwlimit", + "type": "string", + "required": false, + "description": "Set I/O bandwidth limit for various operations (in KiB/s)." + }, + { + "name": "comstar_hg", + "type": "string", + "required": false, + "description": "host group for comstar views" + }, + { + "name": "comstar_tg", + "type": "string", + "required": false, + "description": "target group for comstar views" + }, + { + "name": "content", + "type": "string", + "required": false, + "description": "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.", + "format": "pve-storage-content-list" + }, + { + "name": "content-dirs", + "type": "string", + "required": false, + "description": "Overrides for default content type directories.", + "format": "pve-dir-override-list" + }, + { + "name": "create-base-path", + "type": "boolean", + "required": false, + "description": "Create the base directory if it doesn't exist.", + "default": "yes" + }, + { + "name": "create-subdirs", + "type": "boolean", + "required": false, + "description": "Populate the directory with the default structure.", + "default": "yes" + }, + { + "name": "data-pool", + "type": "string", + "required": false, + "description": "Data Pool (for erasure coding only)" + }, + { + "name": "datastore", + "type": "string", + "required": false, + "description": "Proxmox Backup Server datastore name." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable the storage." + }, + { + "name": "domain", + "type": "string", + "required": false, + "description": "CIFS domain." + }, + { + "name": "encryption-key", + "type": "string", + "required": false, + "description": "Encryption key. Use 'autogen' to generate one automatically without passphrase." + }, + { + "name": "export", + "type": "string", + "required": false, + "description": "NFS export path.", + "format": "pve-storage-path" + }, + { + "name": "fingerprint", + "type": "string", + "required": false, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "format", + "type": "string", + "required": false, + "description": "Default image format.", + "enum": [ + "raw", + "qcow2", + "subvol", + "vmdk" + ] + }, + { + "name": "fs-name", + "type": "string", + "required": false, + "description": "The Ceph filesystem name.", + "format": "pve-configid" + }, + { + "name": "fuse", + "type": "boolean", + "required": false, + "description": "Mount CephFS through FUSE." + }, + { + "name": "is_mountpoint", + "type": "string", + "required": false, + "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.", + "default": "no" + }, + { + "name": "iscsiprovider", + "type": "string", + "required": false, + "description": "iscsi provider" + }, + { + "name": "keyring", + "type": "string", + "required": false, + "description": "Client keyring contents (for external clusters)." + }, + { + "name": "krbd", + "type": "boolean", + "required": false, + "description": "Always access rbd through krbd kernel module.", + "default": 0 + }, + { + "name": "lio_tpg", + "type": "string", + "required": false, + "description": "target portal group for Linux LIO targets" + }, + { + "name": "master-pubkey", + "type": "string", + "required": false, + "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." + }, + { + "name": "max-protected-backups", + "type": "integer", + "required": false, + "description": "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "default": "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "minimum": -1 + }, + { + "name": "mkdir", + "type": "boolean", + "required": false, + "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.", + "default": "yes" + }, + { + "name": "monhost", + "type": "string", + "required": false, + "description": "IP addresses of monitors (for external clusters).", + "format": "pve-storage-portal-dns-list" + }, + { + "name": "mountpoint", + "type": "string", + "required": false, + "description": "mount point", + "format": "pve-storage-path" + }, + { + "name": "namespace", + "type": "string", + "required": false, + "description": "Namespace." + }, + { + "name": "nocow", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of nodes for which the storage configuration applies.", + "format": "pve-node-list" + }, + { + "name": "nowritecache", + "type": "boolean", + "required": false, + "description": "disable write caching on the target" + }, + { + "name": "options", + "type": "string", + "required": false, + "description": "NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')", + "format": "pve-storage-options" + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "Password for accessing the share/datastore." + }, + { + "name": "path", + "type": "string", + "required": false, + "description": "File system path.", + "format": "pve-storage-path" + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Pool." + }, + { + "name": "port", + "type": "integer", + "required": false, + "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.", + "minimum": 1, + "maximum": 65535 + }, + { + "name": "portal", + "type": "string", + "required": false, + "description": "iSCSI portal (IP or DNS name with optional port).", + "format": "pve-storage-portal-dns" + }, + { + "name": "preallocation", + "type": "string", + "required": false, + "description": "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum": [ + "off", + "metadata", + "falloc", + "full" + ], + "default": "metadata" + }, + { + "name": "prune-backups", + "type": "string", + "required": false, + "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" + }, + { + "name": "saferemove", + "type": "boolean", + "required": false, + "description": "Zero-out data when removing LVs." + }, + { + "name": "saferemove_throughput", + "type": "string", + "required": false, + "description": "Wipe throughput (cstream -t parameter value)." + }, + { + "name": "saferemove-stepsize", + "type": "integer", + "required": false, + "description": "Wipe step size in MiB. It will be capped to the maximum supported by the storage.", + "enum": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "default": 32 + }, + { + "name": "server", + "type": "string", + "required": false, + "description": "Server IP or DNS name.", + "format": "pve-storage-server" + }, + { + "name": "share", + "type": "string", + "required": false, + "description": "CIFS share." + }, + { + "name": "shared", + "type": "boolean", + "required": false, + "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!" + }, + { + "name": "skip-cert-verification", + "type": "boolean", + "required": false, + "description": "Disable TLS certificate verification, only enable on fully trusted networks!", + "default": "false" + }, + { + "name": "smbversion", + "type": "string", + "required": false, + "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" + ], + "default": "default" + }, + { + "name": "snapshot-as-volume-chain", + "type": "boolean", + "required": false, + "description": "Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.", + "default": 0 + }, + { + "name": "sparse", + "type": "boolean", + "required": false, + "description": "use sparse volumes" + }, + { + "name": "subdir", + "type": "string", + "required": false, + "description": "Subdir to mount.", + "format": "pve-storage-path" + }, + { + "name": "tagged_only", + "type": "boolean", + "required": false, + "description": "Only list logical volumes tagged with 'pve-vm-ID'." + }, + { + "name": "target", + "type": "string", + "required": false, + "description": "iSCSI target." + }, + { + "name": "thinpool", + "type": "string", + "required": false, + "description": "LVM thin pool LV name.", + "format": "pve-storage-vgname" + }, + { + "name": "username", + "type": "string", + "required": false, + "description": "RBD Id." + }, + { + "name": "vgname", + "type": "string", + "required": false, + "description": "Volume group name.", + "format": "pve-storage-vgname" + }, + { + "name": "zfs-base-path", + "type": "string", + "required": false, + "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" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "POST\n/storage\nstorage\ncreate\nCreate a new storage.\nstorage string The storage identifier.\ntype string Storage type. btrfs cephfs cifs dir esxi iscsi iscsidirect lvm lvmthin nfs pbs rbd zfs zfspool\nauthsupported string Authsupported.\nbase string Base volume. This volume is automatically activated.\nblocksize string ZFS block size\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\ncomstar_hg string host group for comstar views\ncomstar_tg string target group for comstar views\ncontent string Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\ncontent-dirs string Overrides for default content type directories.\ncreate-base-path boolean Create the base directory if it doesn't exist.\ncreate-subdirs boolean Populate the directory with the default structure.\ndata-pool string Data Pool (for erasure coding only)\ndatastore string Proxmox Backup Server datastore name.\ndisable boolean Flag to disable the storage.\ndomain string CIFS domain.\nencryption-key string Encryption key. Use 'autogen' to generate one automatically without passphrase.\nexport string NFS export path.\nfingerprint string Certificate SHA 256 fingerprint.\nformat string Default image format. raw qcow2 subvol vmdk\nfs-name string The Ceph filesystem name.\nfuse boolean Mount CephFS through FUSE.\nis_mountpoint string 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.\niscsiprovider string iscsi provider\nkeyring string Client keyring contents (for external clusters).\nkrbd boolean Always access rbd through krbd kernel module.\nlio_tpg string target portal group for Linux LIO targets\nmaster-pubkey string Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.\nmax-protected-backups integer Maximal number of protected backups per guest. Use '-1' for unlimited.\nmkdir boolean 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.\nmonhost string IP addresses of monitors (for external clusters).\nmountpoint string mount point\nnamespace string Namespace.\nnocow boolean 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.\nnodes string List of nodes for which the storage configuration applies.\nnowritecache boolean disable write caching on the target\noptions string NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')\npassword string Password for accessing the share/datastore.\npath string File system path.\npool string Pool.\nport integer 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.\nportal string iSCSI portal (IP or DNS name with optional port).\npreallocation string Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. off metadata falloc full\nprune-backups string 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.\nsaferemove boolean Zero-out data when removing LVs.\nsaferemove_throughput string Wipe throughput (cstream -t parameter value).\nsaferemove-stepsize integer Wipe step size in MiB. It will be capped to the maximum supported by the storage. 1 2 4 8 16 32\nserver string Server IP or DNS name.\nshare string CIFS share.\nshared boolean 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!\nskip-cert-verification boolean Disable TLS certificate verification, only enable on fully trusted networks!\nsmbversion string SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. default 2.0 2.1 3 3.0 3.11\nsnapshot-as-volume-chain boolean Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.\nsparse boolean use sparse volumes\nsubdir string Subdir to mount.\ntagged_only boolean Only list logical volumes tagged with 'pve-vm-ID'.\ntarget string iSCSI target.\nthinpool string LVM thin pool LV name.\nusername string RBD Id.\nvgname string Volume group name.\nzfs-base-path string Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.\ndatastore\nvolume storage" + }, + { + "id": "DELETE /storage/{storage}", + "method": "DELETE", + "path": "/storage/{storage}", + "section": "storage", + "summary": "delete", + "description": "Delete storage configuration.", + "pathParameters": [ + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [], + "returns": { + "type": "null" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "DELETE\n/storage/{storage}\nstorage\ndelete\nDelete storage configuration.\nstorage string The storage identifier.\ndatastore\nvolume storage" + }, + { + "id": "GET /storage/{storage}", + "method": "GET", + "path": "/storage/{storage}", + "section": "storage", + "summary": "read", + "description": "Read storage configuration.", + "pathParameters": [ + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [], + "returns": { + "type": "object" + }, + "permissions": { + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/storage/{storage}\nstorage\nread\nRead storage configuration.\nstorage string The storage identifier.\ndatastore\nvolume storage" + }, + { + "id": "PUT /storage/{storage}", + "method": "PUT", + "path": "/storage/{storage}", + "section": "storage", + "summary": "update", + "description": "Update storage configuration.", + "pathParameters": [ + { + "name": "storage", + "type": "string", + "required": true, + "description": "The storage identifier.", + "format": "pve-storage-id" + } + ], + "requestParameters": [ + { + "name": "blocksize", + "type": "string", + "required": false, + "description": "ZFS block size", + "format": "pve-storage-zfs-blocksize" + }, + { + "name": "bwlimit", + "type": "string", + "required": false, + "description": "Set I/O bandwidth limit for various operations (in KiB/s)." + }, + { + "name": "comstar_hg", + "type": "string", + "required": false, + "description": "host group for comstar views" + }, + { + "name": "comstar_tg", + "type": "string", + "required": false, + "description": "target group for comstar views" + }, + { + "name": "content", + "type": "string", + "required": false, + "description": "Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.", + "format": "pve-storage-content-list" + }, + { + "name": "content-dirs", + "type": "string", + "required": false, + "description": "Overrides for default content type directories.", + "format": "pve-dir-override-list" + }, + { + "name": "create-base-path", + "type": "boolean", + "required": false, + "description": "Create the base directory if it doesn't exist.", + "default": "yes" + }, + { + "name": "create-subdirs", + "type": "boolean", + "required": false, + "description": "Populate the directory with the default structure.", + "default": "yes" + }, + { + "name": "data-pool", + "type": "string", + "required": false, + "description": "Data Pool (for erasure coding only)" + }, + { + "name": "delete", + "type": "string", + "required": false, + "description": "A list of settings you want to delete.", + "format": "pve-configid-list" + }, + { + "name": "digest", + "type": "string", + "required": false, + "description": "Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "name": "disable", + "type": "boolean", + "required": false, + "description": "Flag to disable the storage." + }, + { + "name": "domain", + "type": "string", + "required": false, + "description": "CIFS domain." + }, + { + "name": "encryption-key", + "type": "string", + "required": false, + "description": "Encryption key. Use 'autogen' to generate one automatically without passphrase." + }, + { + "name": "fingerprint", + "type": "string", + "required": false, + "description": "Certificate SHA 256 fingerprint." + }, + { + "name": "format", + "type": "string", + "required": false, + "description": "Default image format.", + "enum": [ + "raw", + "qcow2", + "subvol", + "vmdk" + ] + }, + { + "name": "fs-name", + "type": "string", + "required": false, + "description": "The Ceph filesystem name.", + "format": "pve-configid" + }, + { + "name": "fuse", + "type": "boolean", + "required": false, + "description": "Mount CephFS through FUSE." + }, + { + "name": "is_mountpoint", + "type": "string", + "required": false, + "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.", + "default": "no" + }, + { + "name": "keyring", + "type": "string", + "required": false, + "description": "Client keyring contents (for external clusters)." + }, + { + "name": "krbd", + "type": "boolean", + "required": false, + "description": "Always access rbd through krbd kernel module.", + "default": 0 + }, + { + "name": "lio_tpg", + "type": "string", + "required": false, + "description": "target portal group for Linux LIO targets" + }, + { + "name": "master-pubkey", + "type": "string", + "required": false, + "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." + }, + { + "name": "max-protected-backups", + "type": "integer", + "required": false, + "description": "Maximal number of protected backups per guest. Use '-1' for unlimited.", + "default": "Unlimited for users with Datastore.Allocate privilege, 5 for other users", + "minimum": -1 + }, + { + "name": "mkdir", + "type": "boolean", + "required": false, + "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.", + "default": "yes" + }, + { + "name": "monhost", + "type": "string", + "required": false, + "description": "IP addresses of monitors (for external clusters).", + "format": "pve-storage-portal-dns-list" + }, + { + "name": "mountpoint", + "type": "string", + "required": false, + "description": "mount point", + "format": "pve-storage-path" + }, + { + "name": "namespace", + "type": "string", + "required": false, + "description": "Namespace." + }, + { + "name": "nocow", + "type": "boolean", + "required": false, + "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.", + "default": 0 + }, + { + "name": "nodes", + "type": "string", + "required": false, + "description": "List of nodes for which the storage configuration applies.", + "format": "pve-node-list" + }, + { + "name": "nowritecache", + "type": "boolean", + "required": false, + "description": "disable write caching on the target" + }, + { + "name": "options", + "type": "string", + "required": false, + "description": "NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')", + "format": "pve-storage-options" + }, + { + "name": "password", + "type": "string", + "required": false, + "description": "Password for accessing the share/datastore." + }, + { + "name": "pool", + "type": "string", + "required": false, + "description": "Pool." + }, + { + "name": "port", + "type": "integer", + "required": false, + "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.", + "minimum": 1, + "maximum": 65535 + }, + { + "name": "preallocation", + "type": "string", + "required": false, + "description": "Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.", + "enum": [ + "off", + "metadata", + "falloc", + "full" + ], + "default": "metadata" + }, + { + "name": "prune-backups", + "type": "string", + "required": false, + "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" + }, + { + "name": "saferemove", + "type": "boolean", + "required": false, + "description": "Zero-out data when removing LVs." + }, + { + "name": "saferemove_throughput", + "type": "string", + "required": false, + "description": "Wipe throughput (cstream -t parameter value)." + }, + { + "name": "saferemove-stepsize", + "type": "integer", + "required": false, + "description": "Wipe step size in MiB. It will be capped to the maximum supported by the storage.", + "enum": [ + "1", + "2", + "4", + "8", + "16", + "32" + ], + "default": 32 + }, + { + "name": "server", + "type": "string", + "required": false, + "description": "Server IP or DNS name.", + "format": "pve-storage-server" + }, + { + "name": "shared", + "type": "boolean", + "required": false, + "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!" + }, + { + "name": "skip-cert-verification", + "type": "boolean", + "required": false, + "description": "Disable TLS certificate verification, only enable on fully trusted networks!", + "default": "false" + }, + { + "name": "smbversion", + "type": "string", + "required": false, + "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" + ], + "default": "default" + }, + { + "name": "snapshot-as-volume-chain", + "type": "boolean", + "required": false, + "description": "Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.", + "default": 0 + }, + { + "name": "sparse", + "type": "boolean", + "required": false, + "description": "use sparse volumes" + }, + { + "name": "subdir", + "type": "string", + "required": false, + "description": "Subdir to mount.", + "format": "pve-storage-path" + }, + { + "name": "tagged_only", + "type": "boolean", + "required": false, + "description": "Only list logical volumes tagged with 'pve-vm-ID'." + }, + { + "name": "username", + "type": "string", + "required": false, + "description": "RBD Id." + }, + { + "name": "zfs-base-path", + "type": "string", + "required": false, + "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" + } + ], + "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" + }, + "permissions": { + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] + }, + "raw": { + "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" + } + }, + "searchText": "PUT\n/storage/{storage}\nstorage\nupdate\nUpdate storage configuration.\nstorage string The storage identifier.\nblocksize string ZFS block size\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\ncomstar_hg string host group for comstar views\ncomstar_tg string target group for comstar views\ncontent string Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\ncontent-dirs string Overrides for default content type directories.\ncreate-base-path boolean Create the base directory if it doesn't exist.\ncreate-subdirs boolean Populate the directory with the default structure.\ndata-pool string Data Pool (for erasure coding only)\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the storage.\ndomain string CIFS domain.\nencryption-key string Encryption key. Use 'autogen' to generate one automatically without passphrase.\nfingerprint string Certificate SHA 256 fingerprint.\nformat string Default image format. raw qcow2 subvol vmdk\nfs-name string The Ceph filesystem name.\nfuse boolean Mount CephFS through FUSE.\nis_mountpoint string 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.\nkeyring string Client keyring contents (for external clusters).\nkrbd boolean Always access rbd through krbd kernel module.\nlio_tpg string target portal group for Linux LIO targets\nmaster-pubkey string Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.\nmax-protected-backups integer Maximal number of protected backups per guest. Use '-1' for unlimited.\nmkdir boolean 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.\nmonhost string IP addresses of monitors (for external clusters).\nmountpoint string mount point\nnamespace string Namespace.\nnocow boolean 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.\nnodes string List of nodes for which the storage configuration applies.\nnowritecache boolean disable write caching on the target\noptions string NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')\npassword string Password for accessing the share/datastore.\npool string Pool.\nport integer 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.\npreallocation string Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. off metadata falloc full\nprune-backups string 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.\nsaferemove boolean Zero-out data when removing LVs.\nsaferemove_throughput string Wipe throughput (cstream -t parameter value).\nsaferemove-stepsize integer Wipe step size in MiB. It will be capped to the maximum supported by the storage. 1 2 4 8 16 32\nserver string Server IP or DNS name.\nshared boolean 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!\nskip-cert-verification boolean Disable TLS certificate verification, only enable on fully trusted networks!\nsmbversion string SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. default 2.0 2.1 3 3.0 3.11\nsnapshot-as-volume-chain boolean Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.\nsparse boolean use sparse volumes\nsubdir string Subdir to mount.\ntagged_only boolean Only list logical volumes tagged with 'pve-vm-ID'.\nusername string RBD Id.\nzfs-base-path string Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.\ndatastore\nvolume storage" + }, + { + "id": "GET /version", + "method": "GET", + "path": "/version", + "section": "version", + "summary": "version", + "description": "API version details, including some parts of the global datacenter config.", + "pathParameters": [], + "requestParameters": [], + "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" + }, + "permissions": { + "user": "all" + }, + "raw": { + "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" + } + }, + "searchText": "GET\n/version\nversion\nversion\nAPI version details, including some parts of the global datacenter config." + } +] diff --git a/docs/pve-api/endpoints.ndjson b/docs/pve-api/endpoints.ndjson new file mode 100644 index 00000000000..0b2a0c76bc9 --- /dev/null +++ b/docs/pve-api/endpoints.ndjson @@ -0,0 +1,675 @@ +{"id":"GET /access","method":"GET","path":"/access","section":"access","summary":"index","description":"Directory index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/access\naccess\nindex\nDirectory index."} +{"id":"GET /access/acl","method":"GET","path":"/access/acl","section":"access","summary":"read_acl","description":"Get Access Control List (ACLs).","pathParameters":[],"requestParameters":[],"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"},"permissions":{"description":"The returned list is restricted to objects where you have rights to modify permissions.","user":"all"},"raw":{"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"}},"searchText":"GET\n/access/acl\naccess\nread_acl\nGet Access Control List (ACLs)."} +{"id":"PUT /access/acl","method":"PUT","path":"/access/acl","section":"access","summary":"update_acl","description":"Update Access Control List (add or remove permissions).","pathParameters":[],"requestParameters":[{"name":"path","type":"string","required":true,"description":"Access control path"},{"name":"roles","type":"string","required":true,"description":"List of roles.","format":"pve-roleid-list"},{"name":"delete","type":"boolean","required":false,"description":"Remove permissions (instead of adding it)."},{"name":"groups","type":"string","required":false,"description":"List of groups.","format":"pve-groupid-list"},{"name":"propagate","type":"boolean","required":false,"description":"Allow to propagate (inherit) permissions.","default":1},{"name":"tokens","type":"string","required":false,"description":"List of API tokens.","format":"pve-tokenid-list"},{"name":"users","type":"string","required":false,"description":"List of users.","format":"pve-userid-list"}],"returns":{"type":"null"},"permissions":{"check":["perm-modify","{path}"]},"raw":{"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"}},"searchText":"PUT\n/access/acl\naccess\nupdate_acl\nUpdate Access Control List (add or remove permissions).\npath string Access control path\nroles string List of roles.\ndelete boolean Remove permissions (instead of adding it).\ngroups string List of groups.\npropagate boolean Allow to propagate (inherit) permissions.\ntokens string List of API tokens.\nusers string List of users."} +{"id":"GET /access/domains","method":"GET","path":"/access/domains","section":"access","summary":"index","description":"Authentication domain index.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"description":"Anyone can access that, because we need that list for the login box (before the user is authenticated).","user":"world"},"raw":{"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"}},"searchText":"GET\n/access/domains\naccess\nindex\nAuthentication domain index."} +{"id":"POST /access/domains","method":"POST","path":"/access/domains","section":"access","summary":"create","description":"Add an authentication server.","pathParameters":[],"requestParameters":[{"name":"realm","type":"string","required":true,"description":"Authentication domain ID","format":"pve-realm"},{"name":"type","type":"string","required":true,"description":"Realm type.","enum":["ad","ldap","openid","pam","pve"]},{"name":"acr-values","type":"string","required":false,"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request."},{"name":"audiences","type":"string","required":false,"description":"A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'."},{"name":"autocreate","type":"boolean","required":false,"description":"Automatically create users if they do not exist.","default":0},{"name":"base_dn","type":"string","required":false,"description":"LDAP base domain name"},{"name":"bind_dn","type":"string","required":false,"description":"LDAP bind domain name"},{"name":"capath","type":"string","required":false,"description":"Path to the CA certificate store","default":"/etc/ssl/certs"},{"name":"case-sensitive","type":"boolean","required":false,"description":"username is case-sensitive","default":1},{"name":"cert","type":"string","required":false,"description":"Path to the client certificate"},{"name":"certkey","type":"string","required":false,"description":"Path to the client certificate key"},{"name":"check-connection","type":"boolean","required":false,"description":"Check bind connection to the server.","default":0},{"name":"client-id","type":"string","required":false,"description":"OpenID Client ID"},{"name":"client-key","type":"string","required":false,"description":"OpenID Client Key"},{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"default","type":"boolean","required":false,"description":"Use this as default realm"},{"name":"domain","type":"string","required":false,"description":"AD domain name"},{"name":"filter","type":"string","required":false,"description":"LDAP filter for user sync."},{"name":"group_classes","type":"string","required":false,"description":"The objectclasses for groups.","default":"groupOfNames, group, univentionGroup, ipausergroup","format":"ldap-simple-attr-list"},{"name":"group_dn","type":"string","required":false,"description":"LDAP base domain name for group sync. If not set, the base_dn will be used."},{"name":"group_filter","type":"string","required":false,"description":"LDAP filter for group sync."},{"name":"group_name_attr","type":"string","required":false,"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"},{"name":"groups-autocreate","type":"boolean","required":false,"description":"Automatically create groups if they do not exist.","default":0},{"name":"groups-claim","type":"string","required":false,"description":"OpenID claim used to retrieve groups with."},{"name":"groups-overwrite","type":"boolean","required":false,"description":"All groups will be overwritten for the user on login.","default":0},{"name":"issuer-url","type":"string","required":false,"description":"OpenID Issuer Url"},{"name":"mode","type":"string","required":false,"description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"default":"ldap"},{"name":"password","type":"string","required":false,"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'."},{"name":"port","type":"integer","required":false,"description":"Server port.","minimum":1,"maximum":65535},{"name":"prompt","type":"string","required":false,"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent."},{"name":"query-userinfo","type":"boolean","required":false,"description":"Enables querying the userinfo endpoint for claims values.","default":1},{"name":"scopes","type":"string","required":false,"description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","default":"email profile"},{"name":"secure","type":"boolean","required":false,"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead."},{"name":"server1","type":"string","required":false,"description":"Server IP address (or DNS name)","format":"address"},{"name":"server2","type":"string","required":false,"description":"Fallback Server IP address (or DNS name)","format":"address"},{"name":"sslversion","type":"string","required":false,"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"]},{"name":"sync_attributes","type":"string","required":false,"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."},{"name":"sync-defaults-options","type":"string","required":false,"description":"The default options for behavior of synchronizations.","format":"realm-sync-options"},{"name":"tfa","type":"string","required":false,"description":"Use Two-factor authentication.","format":"pve-tfa-config"},{"name":"user_attr","type":"string","required":false,"description":"LDAP user attribute name"},{"name":"user_classes","type":"string","required":false,"description":"The objectclasses for users.","default":"inetorgperson, posixaccount, person, user","format":"ldap-simple-attr-list"},{"name":"username-claim","type":"string","required":false,"description":"OpenID claim used to generate the unique username."},{"name":"verify","type":"boolean","required":false,"description":"Verify the server's SSL certificate","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/access/realm",["Realm.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/access/domains\naccess\ncreate\nAdd an authentication server.\nrealm string Authentication domain ID\ntype string Realm type. ad ldap openid pam pve\nacr-values string Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.\naudiences string A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.\nautocreate boolean Automatically create users if they do not exist.\nbase_dn string LDAP base domain name\nbind_dn string LDAP bind domain name\ncapath string Path to the CA certificate store\ncase-sensitive boolean username is case-sensitive\ncert string Path to the client certificate\ncertkey string Path to the client certificate key\ncheck-connection boolean Check bind connection to the server.\nclient-id string OpenID Client ID\nclient-key string OpenID Client Key\ncomment string Description.\ndefault boolean Use this as default realm\ndomain string AD domain name\nfilter string LDAP filter for user sync.\ngroup_classes string The objectclasses for groups.\ngroup_dn string LDAP base domain name for group sync. If not set, the base_dn will be used.\ngroup_filter string LDAP filter for group sync.\ngroup_name_attr string LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.\ngroups-autocreate boolean Automatically create groups if they do not exist.\ngroups-claim string OpenID claim used to retrieve groups with.\ngroups-overwrite boolean All groups will be overwritten for the user on login.\nissuer-url string OpenID Issuer Url\nmode string LDAP protocol mode. ldap ldaps ldap+starttls\npassword string LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.\nport integer Server port.\nprompt string Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.\nquery-userinfo boolean Enables querying the userinfo endpoint for claims values.\nscopes string Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.\nsecure boolean Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.\nserver1 string Server IP address (or DNS name)\nserver2 string Fallback Server IP address (or DNS name)\nsslversion string LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! tlsv1 tlsv1_1 tlsv1_2 tlsv1_3\nsync_attributes string 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.\nsync-defaults-options string The default options for behavior of synchronizations.\ntfa string Use Two-factor authentication.\nuser_attr string LDAP user attribute name\nuser_classes string The objectclasses for users.\nusername-claim string OpenID claim used to generate the unique username.\nverify boolean Verify the server's SSL certificate"} +{"id":"DELETE /access/domains/{realm}","method":"DELETE","path":"/access/domains/{realm}","section":"access","summary":"delete","description":"Delete an authentication server.","pathParameters":[{"name":"realm","type":"string","required":true,"description":"Authentication domain ID","format":"pve-realm"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/access/realm",["Realm.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/access/domains/{realm}\naccess\ndelete\nDelete an authentication server.\nrealm string Authentication domain ID"} +{"id":"GET /access/domains/{realm}","method":"GET","path":"/access/domains/{realm}","section":"access","summary":"read","description":"Get auth server configuration.","pathParameters":[{"name":"realm","type":"string","required":true,"description":"Authentication domain ID","format":"pve-realm"}],"requestParameters":[],"returns":{},"permissions":{"check":["perm","/access/realm",["Realm.Allocate","Sys.Audit"],"any",1]},"raw":{"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":{}},"searchText":"GET\n/access/domains/{realm}\naccess\nread\nGet auth server configuration.\nrealm string Authentication domain ID"} +{"id":"PUT /access/domains/{realm}","method":"PUT","path":"/access/domains/{realm}","section":"access","summary":"update","description":"Update authentication server settings.","pathParameters":[{"name":"realm","type":"string","required":true,"description":"Authentication domain ID","format":"pve-realm"}],"requestParameters":[{"name":"acr-values","type":"string","required":false,"description":"Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request."},{"name":"audiences","type":"string","required":false,"description":"A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'."},{"name":"autocreate","type":"boolean","required":false,"description":"Automatically create users if they do not exist.","default":0},{"name":"base_dn","type":"string","required":false,"description":"LDAP base domain name"},{"name":"bind_dn","type":"string","required":false,"description":"LDAP bind domain name"},{"name":"capath","type":"string","required":false,"description":"Path to the CA certificate store","default":"/etc/ssl/certs"},{"name":"case-sensitive","type":"boolean","required":false,"description":"username is case-sensitive","default":1},{"name":"cert","type":"string","required":false,"description":"Path to the client certificate"},{"name":"certkey","type":"string","required":false,"description":"Path to the client certificate key"},{"name":"check-connection","type":"boolean","required":false,"description":"Check bind connection to the server.","default":0},{"name":"client-id","type":"string","required":false,"description":"OpenID Client ID"},{"name":"client-key","type":"string","required":false,"description":"OpenID Client Key"},{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"default","type":"boolean","required":false,"description":"Use this as default realm"},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"domain","type":"string","required":false,"description":"AD domain name"},{"name":"filter","type":"string","required":false,"description":"LDAP filter for user sync."},{"name":"group_classes","type":"string","required":false,"description":"The objectclasses for groups.","default":"groupOfNames, group, univentionGroup, ipausergroup","format":"ldap-simple-attr-list"},{"name":"group_dn","type":"string","required":false,"description":"LDAP base domain name for group sync. If not set, the base_dn will be used."},{"name":"group_filter","type":"string","required":false,"description":"LDAP filter for group sync."},{"name":"group_name_attr","type":"string","required":false,"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"},{"name":"groups-autocreate","type":"boolean","required":false,"description":"Automatically create groups if they do not exist.","default":0},{"name":"groups-claim","type":"string","required":false,"description":"OpenID claim used to retrieve groups with."},{"name":"groups-overwrite","type":"boolean","required":false,"description":"All groups will be overwritten for the user on login.","default":0},{"name":"issuer-url","type":"string","required":false,"description":"OpenID Issuer Url"},{"name":"mode","type":"string","required":false,"description":"LDAP protocol mode.","enum":["ldap","ldaps","ldap+starttls"],"default":"ldap"},{"name":"password","type":"string","required":false,"description":"LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'."},{"name":"port","type":"integer","required":false,"description":"Server port.","minimum":1,"maximum":65535},{"name":"prompt","type":"string","required":false,"description":"Specifies whether the Authorization Server prompts the End-User for reauthentication and consent."},{"name":"query-userinfo","type":"boolean","required":false,"description":"Enables querying the userinfo endpoint for claims values.","default":1},{"name":"scopes","type":"string","required":false,"description":"Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.","default":"email profile"},{"name":"secure","type":"boolean","required":false,"description":"Use secure LDAPS protocol. DEPRECATED: use 'mode' instead."},{"name":"server1","type":"string","required":false,"description":"Server IP address (or DNS name)","format":"address"},{"name":"server2","type":"string","required":false,"description":"Fallback Server IP address (or DNS name)","format":"address"},{"name":"sslversion","type":"string","required":false,"description":"LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!","enum":["tlsv1","tlsv1_1","tlsv1_2","tlsv1_3"]},{"name":"sync_attributes","type":"string","required":false,"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."},{"name":"sync-defaults-options","type":"string","required":false,"description":"The default options for behavior of synchronizations.","format":"realm-sync-options"},{"name":"tfa","type":"string","required":false,"description":"Use Two-factor authentication.","format":"pve-tfa-config"},{"name":"user_attr","type":"string","required":false,"description":"LDAP user attribute name"},{"name":"user_classes","type":"string","required":false,"description":"The objectclasses for users.","default":"inetorgperson, posixaccount, person, user","format":"ldap-simple-attr-list"},{"name":"verify","type":"boolean","required":false,"description":"Verify the server's SSL certificate","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/access/realm",["Realm.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/access/domains/{realm}\naccess\nupdate\nUpdate authentication server settings.\nrealm string Authentication domain ID\nacr-values string Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.\naudiences string A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.\nautocreate boolean Automatically create users if they do not exist.\nbase_dn string LDAP base domain name\nbind_dn string LDAP bind domain name\ncapath string Path to the CA certificate store\ncase-sensitive boolean username is case-sensitive\ncert string Path to the client certificate\ncertkey string Path to the client certificate key\ncheck-connection boolean Check bind connection to the server.\nclient-id string OpenID Client ID\nclient-key string OpenID Client Key\ncomment string Description.\ndefault boolean Use this as default realm\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndomain string AD domain name\nfilter string LDAP filter for user sync.\ngroup_classes string The objectclasses for groups.\ngroup_dn string LDAP base domain name for group sync. If not set, the base_dn will be used.\ngroup_filter string LDAP filter for group sync.\ngroup_name_attr string LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.\ngroups-autocreate boolean Automatically create groups if they do not exist.\ngroups-claim string OpenID claim used to retrieve groups with.\ngroups-overwrite boolean All groups will be overwritten for the user on login.\nissuer-url string OpenID Issuer Url\nmode string LDAP protocol mode. ldap ldaps ldap+starttls\npassword string LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.\nport integer Server port.\nprompt string Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.\nquery-userinfo boolean Enables querying the userinfo endpoint for claims values.\nscopes string Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.\nsecure boolean Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.\nserver1 string Server IP address (or DNS name)\nserver2 string Fallback Server IP address (or DNS name)\nsslversion string LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! tlsv1 tlsv1_1 tlsv1_2 tlsv1_3\nsync_attributes string 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.\nsync-defaults-options string The default options for behavior of synchronizations.\ntfa string Use Two-factor authentication.\nuser_attr string LDAP user attribute name\nuser_classes string The objectclasses for users.\nverify boolean Verify the server's SSL certificate"} +{"id":"POST /access/domains/{realm}/sync","method":"POST","path":"/access/domains/{realm}/sync","section":"access","summary":"sync","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.","pathParameters":[{"name":"realm","type":"string","required":true,"description":"Authentication domain ID","format":"pve-realm"}],"requestParameters":[{"name":"enable-new","type":"boolean","required":true,"description":"Enable newly synced users immediately.","default":"1"},{"name":"full","type":"boolean","required":true,"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."},{"name":"purge","type":"boolean","required":true,"description":"DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync."},{"name":"remove-vanished","type":"string","required":true,"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).","default":"none"},{"name":"scope","type":"string","required":true,"description":"Select what to sync.","enum":["users","groups","both"]},{"name":"dry-run","type":"boolean","required":false,"description":"If set, does not write anything.","default":0}],"returns":{"description":"Worker Task-UPID","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/'."},"raw":{"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"}},"searchText":"POST\n/access/domains/{realm}/sync\naccess\nsync\nSyncs 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.\nrealm string Authentication domain ID\nenable-new boolean Enable newly synced users immediately.\nfull boolean 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.\npurge boolean DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.\nremove-vanished string 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).\nscope string Select what to sync. users groups both\ndry-run boolean If set, does not write anything."} +{"id":"GET /access/groups","method":"GET","path":"/access/groups","section":"access","summary":"index","description":"Group index.","pathParameters":[],"requestParameters":[],"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"},"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"},"raw":{"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"}},"searchText":"GET\n/access/groups\naccess\nindex\nGroup index."} +{"id":"POST /access/groups","method":"POST","path":"/access/groups","section":"access","summary":"create_group","description":"Create new group.","pathParameters":[],"requestParameters":[{"name":"groupid","type":"string","required":true,"format":"pve-groupid"},{"name":"comment","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/access/groups",["Group.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/access/groups\naccess\ncreate_group\nCreate new group.\ngroupid string\ncomment string"} +{"id":"DELETE /access/groups/{groupid}","method":"DELETE","path":"/access/groups/{groupid}","section":"access","summary":"delete_group","description":"Delete group.","pathParameters":[{"name":"groupid","type":"string","required":true,"format":"pve-groupid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/access/groups",["Group.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/access/groups/{groupid}\naccess\ndelete_group\nDelete group.\ngroupid string"} +{"id":"GET /access/groups/{groupid}","method":"GET","path":"/access/groups/{groupid}","section":"access","summary":"read_group","description":"Get group configuration.","pathParameters":[{"name":"groupid","type":"string","required":true,"format":"pve-groupid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/access/groups",["Sys.Audit","Group.Allocate"],"any",1]},"raw":{"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"}},"searchText":"GET\n/access/groups/{groupid}\naccess\nread_group\nGet group configuration.\ngroupid string"} +{"id":"PUT /access/groups/{groupid}","method":"PUT","path":"/access/groups/{groupid}","section":"access","summary":"update_group","description":"Update group data.","pathParameters":[{"name":"groupid","type":"string","required":true,"format":"pve-groupid"}],"requestParameters":[{"name":"comment","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/access/groups",["Group.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/access/groups/{groupid}\naccess\nupdate_group\nUpdate group data.\ngroupid string\ncomment string"} +{"id":"GET /access/openid","method":"GET","path":"/access/openid","section":"access","summary":"index","description":"Directory index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/access/openid\naccess\nindex\nDirectory index."} +{"id":"POST /access/openid/auth-url","method":"POST","path":"/access/openid/auth-url","section":"access","summary":"auth_url","description":"Get the OpenId Authorization Url for the specified realm.","pathParameters":[],"requestParameters":[{"name":"realm","type":"string","required":true,"description":"Authentication domain ID","format":"pve-realm"},{"name":"redirect-url","type":"string","required":true,"description":"Redirection Url. The client should set this to the used server url (location.origin)."}],"returns":{"description":"Redirection URL.","type":"string"},"permissions":{"user":"world"},"raw":{"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"}},"searchText":"POST\n/access/openid/auth-url\naccess\nauth_url\nGet the OpenId Authorization Url for the specified realm.\nrealm string Authentication domain ID\nredirect-url string Redirection Url. The client should set this to the used server url (location.origin)."} +{"id":"POST /access/openid/login","method":"POST","path":"/access/openid/login","section":"access","summary":"login","description":"Verify OpenID authorization code and create a ticket.","pathParameters":[],"requestParameters":[{"name":"code","type":"string","required":true,"description":"OpenId authorization code."},{"name":"redirect-url","type":"string","required":true,"description":"Redirection Url. The client should set this to the used server url (location.origin)."},{"name":"state","type":"string","required":true,"description":"OpenId state."}],"returns":{"properties":{"CSRFPreventionToken":{"type":"string"},"cap":{"type":"object"},"clustername":{"optional":1,"type":"string"},"ticket":{"type":"string"},"username":{"type":"string"}}},"permissions":{"user":"world"},"raw":{"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"}}}},"searchText":"POST\n/access/openid/login\naccess\nlogin\nVerify OpenID authorization code and create a ticket.\ncode string OpenId authorization code.\nredirect-url string Redirection Url. The client should set this to the used server url (location.origin).\nstate string OpenId state."} +{"id":"PUT /access/password","method":"PUT","path":"/access/password","section":"access","summary":"change_password","description":"Change user password.","pathParameters":[],"requestParameters":[{"name":"password","type":"string","required":true,"description":"The new password."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"},{"name":"confirmation-password","type":"string","required":false,"description":"The current password of the user performing the change."}],"returns":{"type":"null"},"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."},"raw":{"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"}},"searchText":"PUT\n/access/password\naccess\nchange_password\nChange user password.\npassword string The new password.\nuserid string Full User ID, in the `name@realm` format.\nconfirmation-password string The current password of the user performing the change."} +{"id":"GET /access/permissions","method":"GET","path":"/access/permissions","section":"access","summary":"permissions","description":"Retrieve effective permissions of given user/token.","pathParameters":[],"requestParameters":[{"name":"path","type":"string","required":false,"description":"Only dump this specific path, not the whole tree."},{"name":"userid","type":"string","required":false,"description":"User ID or full API token ID"}],"returns":{"description":"Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").","type":"object"},"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"},"raw":{"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"}},"searchText":"GET\n/access/permissions\naccess\npermissions\nRetrieve effective permissions of given user/token.\npath string Only dump this specific path, not the whole tree.\nuserid string User ID or full API token ID"} +{"id":"GET /access/roles","method":"GET","path":"/access/roles","section":"access","summary":"index","description":"Role index.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/access/roles\naccess\nindex\nRole index."} +{"id":"POST /access/roles","method":"POST","path":"/access/roles","section":"access","summary":"create_role","description":"Create new role.","pathParameters":[],"requestParameters":[{"name":"roleid","type":"string","required":true,"format":"pve-roleid"},{"name":"privs","type":"string","required":false,"format":"pve-priv-list"}],"returns":{"type":"null"},"permissions":{"check":["perm","/access",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/access/roles\naccess\ncreate_role\nCreate new role.\nroleid string\nprivs string"} +{"id":"DELETE /access/roles/{roleid}","method":"DELETE","path":"/access/roles/{roleid}","section":"access","summary":"delete_role","description":"Delete role.","pathParameters":[{"name":"roleid","type":"string","required":true,"format":"pve-roleid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/access",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/access/roles/{roleid}\naccess\ndelete_role\nDelete role.\nroleid string"} +{"id":"GET /access/roles/{roleid}","method":"GET","path":"/access/roles/{roleid}","section":"access","summary":"read_role","description":"Get role configuration.","pathParameters":[{"name":"roleid","type":"string","required":true,"format":"pve-roleid"}],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/access/roles/{roleid}\naccess\nread_role\nGet role configuration.\nroleid string"} +{"id":"PUT /access/roles/{roleid}","method":"PUT","path":"/access/roles/{roleid}","section":"access","summary":"update_role","description":"Update an existing role.","pathParameters":[{"name":"roleid","type":"string","required":true,"format":"pve-roleid"}],"requestParameters":[{"name":"append","type":"boolean","required":false},{"name":"privs","type":"string","required":false,"format":"pve-priv-list"}],"returns":{"type":"null"},"permissions":{"check":["perm","/access",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/access/roles/{roleid}\naccess\nupdate_role\nUpdate an existing role.\nroleid string\nappend boolean\nprivs string"} +{"id":"GET /access/tfa","method":"GET","path":"/access/tfa","section":"access","summary":"list_tfa","description":"List TFA configurations of users.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"description":"Returns all or just the logged-in user, depending on privileges.","user":"all"},"raw":{"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"}},"searchText":"GET\n/access/tfa\naccess\nlist_tfa\nList TFA configurations of users."} +{"id":"GET /access/tfa/{userid}","method":"GET","path":"/access/tfa/{userid}","section":"access","summary":"list_user_tfa","description":"List TFA configurations of users.","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/access/tfa/{userid}\naccess\nlist_user_tfa\nList TFA configurations of users.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"POST /access/tfa/{userid}","method":"POST","path":"/access/tfa/{userid}","section":"access","summary":"add_tfa_entry","description":"Add a TFA entry for a user.","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[{"name":"type","type":"string","required":true,"description":"TFA Entry Type.","enum":["totp","u2f","webauthn","recovery","yubico"]},{"name":"challenge","type":"string","required":false,"description":"When responding to a u2f challenge: the original challenge string"},{"name":"description","type":"string","required":false,"description":"A description to distinguish multiple entries from one another"},{"name":"password","type":"string","required":false,"description":"The current password of the user performing the change."},{"name":"totp","type":"string","required":false,"description":"A totp URI."},{"name":"value","type":"string","required":false,"description":"The current value for the provided totp URI, or a Webauthn/U2F challenge response"}],"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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"POST\n/access/tfa/{userid}\naccess\nadd_tfa_entry\nAdd a TFA entry for a user.\nuserid string Full User ID, in the `name@realm` format.\ntype string TFA Entry Type. totp u2f webauthn recovery yubico\nchallenge string When responding to a u2f challenge: the original challenge string\ndescription string A description to distinguish multiple entries from one another\npassword string The current password of the user performing the change.\ntotp string A totp URI.\nvalue string The current value for the provided totp URI, or a Webauthn/U2F challenge response"} +{"id":"DELETE /access/tfa/{userid}/{id}","method":"DELETE","path":"/access/tfa/{userid}/{id}","section":"access","summary":"delete_tfa","description":"Delete a TFA entry by ID.","pathParameters":[{"name":"id","type":"string","required":true,"description":"A TFA entry id."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[{"name":"password","type":"string","required":false,"description":"The current password of the user performing the change."}],"returns":{"type":"null"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"DELETE\n/access/tfa/{userid}/{id}\naccess\ndelete_tfa\nDelete a TFA entry by ID.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format.\npassword string The current password of the user performing the change."} +{"id":"GET /access/tfa/{userid}/{id}","method":"GET","path":"/access/tfa/{userid}/{id}","section":"access","summary":"get_tfa_entry","description":"Fetch a requested TFA entry if present.","pathParameters":[{"name":"id","type":"string","required":true,"description":"A TFA entry id."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/access/tfa/{userid}/{id}\naccess\nget_tfa_entry\nFetch a requested TFA entry if present.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"PUT /access/tfa/{userid}/{id}","method":"PUT","path":"/access/tfa/{userid}/{id}","section":"access","summary":"update_tfa_entry","description":"Add a TFA entry for a user.","pathParameters":[{"name":"id","type":"string","required":true,"description":"A TFA entry id."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[{"name":"description","type":"string","required":false,"description":"A description to distinguish multiple entries from one another"},{"name":"enable","type":"boolean","required":false,"description":"Whether the entry should be enabled for login."},{"name":"password","type":"string","required":false,"description":"The current password of the user performing the change."}],"returns":{"type":"null"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"PUT\n/access/tfa/{userid}/{id}\naccess\nupdate_tfa_entry\nAdd a TFA entry for a user.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format.\ndescription string A description to distinguish multiple entries from one another\nenable boolean Whether the entry should be enabled for login.\npassword string The current password of the user performing the change."} +{"id":"GET /access/ticket","method":"GET","path":"/access/ticket","section":"access","summary":"get_ticket","description":"Dummy. Useful for formatters which want to provide a login page.","pathParameters":[],"requestParameters":[],"returns":{"type":"null"},"permissions":{"user":"world"},"raw":{"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"}},"searchText":"GET\n/access/ticket\naccess\nget_ticket\nDummy. Useful for formatters which want to provide a login page."} +{"id":"POST /access/ticket","method":"POST","path":"/access/ticket","section":"access","summary":"create_ticket","description":"Create or verify authentication ticket.","pathParameters":[],"requestParameters":[{"name":"password","type":"string","required":true,"description":"The secret password. This can also be a valid ticket."},{"name":"username","type":"string","required":true,"description":"User name"},{"name":"new-format","type":"boolean","required":false,"description":"This parameter is now ignored and assumed to be 1.","default":1},{"name":"otp","type":"string","required":false,"description":"One-time password for Two-factor authentication."},{"name":"path","type":"string","required":false,"description":"Verify ticket, and check if user have access 'privs' on 'path'"},{"name":"privs","type":"string","required":false,"description":"Verify ticket, and check if user have access 'privs' on 'path'","format":"pve-priv-list"},{"name":"realm","type":"string","required":false,"description":"You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.","format":"pve-realm"},{"name":"tfa-challenge","type":"string","required":false,"description":"The signed TFA challenge string the user wants to respond to."}],"returns":{"properties":{"CSRFPreventionToken":{"optional":1,"type":"string"},"clustername":{"optional":1,"type":"string"},"ticket":{"optional":1,"type":"string"},"username":{"type":"string"}},"type":"object"},"permissions":{"description":"You need to pass valid credientials.","user":"world"},"raw":{"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"}},"searchText":"POST\n/access/ticket\naccess\ncreate_ticket\nCreate or verify authentication ticket.\npassword string The secret password. This can also be a valid ticket.\nusername string User name\nnew-format boolean This parameter is now ignored and assumed to be 1.\notp string One-time password for Two-factor authentication.\npath string Verify ticket, and check if user have access 'privs' on 'path'\nprivs string Verify ticket, and check if user have access 'privs' on 'path'\nrealm string You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.\ntfa-challenge string The signed TFA challenge string the user wants to respond to."} +{"id":"GET /access/users","method":"GET","path":"/access/users","section":"access","summary":"index","description":"User index.","pathParameters":[],"requestParameters":[{"name":"enabled","type":"boolean","required":false,"description":"Optional filter for enable property."},{"name":"full","type":"boolean","required":false,"description":"Include group and token information.","default":0}],"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"},"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"},"raw":{"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"}},"searchText":"GET\n/access/users\naccess\nindex\nUser index.\nenabled boolean Optional filter for enable property.\nfull boolean Include group and token information."} +{"id":"POST /access/users","method":"POST","path":"/access/users","section":"access","summary":"create_user","description":"Create new user.","pathParameters":[],"requestParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"},{"name":"comment","type":"string","required":false},{"name":"email","type":"string","required":false,"format":"email-opt"},{"name":"enable","type":"boolean","required":false,"description":"Enable the account (default). You can set this to '0' to disable the account","default":1},{"name":"expire","type":"integer","required":false,"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","minimum":0},{"name":"firstname","type":"string","required":false},{"name":"groups","type":"string","required":false,"format":"pve-groupid-list"},{"name":"keys","type":"string","required":false,"description":"Keys for two factor auth (yubico)."},{"name":"lastname","type":"string","required":false},{"name":"password","type":"string","required":false,"description":"Initial password."}],"returns":{"type":"null"},"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."},"raw":{"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"}},"searchText":"POST\n/access/users\naccess\ncreate_user\nCreate new user.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\nemail string\nenable boolean Enable the account (default). You can set this to '0' to disable the account\nexpire integer Account expiration date (seconds since epoch). '0' means no expiration date.\nfirstname string\ngroups string\nkeys string Keys for two factor auth (yubico).\nlastname string\npassword string Initial password."} +{"id":"DELETE /access/users/{userid}","method":"DELETE","path":"/access/users/{userid}","section":"access","summary":"delete_user","description":"Delete user.","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["and",["userid-param","Realm.AllocateUser"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"DELETE\n/access/users/{userid}\naccess\ndelete_user\nDelete user.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"GET /access/users/{userid}","method":"GET","path":"/access/users/{userid}","section":"access","summary":"read_user","description":"Get user configuration.","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"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"},"permissions":{"check":["userid-group",["User.Modify","Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/access/users/{userid}\naccess\nread_user\nGet user configuration.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"PUT /access/users/{userid}","method":"PUT","path":"/access/users/{userid}","section":"access","summary":"update_user","description":"Update user configuration.","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[{"name":"append","type":"boolean","required":false},{"name":"comment","type":"string","required":false},{"name":"email","type":"string","required":false,"format":"email-opt"},{"name":"enable","type":"boolean","required":false,"description":"Enable the account (default). You can set this to '0' to disable the account","default":1},{"name":"expire","type":"integer","required":false,"description":"Account expiration date (seconds since epoch). '0' means no expiration date.","minimum":0},{"name":"firstname","type":"string","required":false},{"name":"groups","type":"string","required":false,"format":"pve-groupid-list"},{"name":"keys","type":"string","required":false,"description":"Keys for two factor auth (yubico)."},{"name":"lastname","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["userid-group",["User.Modify"],"groups_param","update"]},"raw":{"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"}},"searchText":"PUT\n/access/users/{userid}\naccess\nupdate_user\nUpdate user configuration.\nuserid string Full User ID, in the `name@realm` format.\nappend boolean\ncomment string\nemail string\nenable boolean Enable the account (default). You can set this to '0' to disable the account\nexpire integer Account expiration date (seconds since epoch). '0' means no expiration date.\nfirstname string\ngroups string\nkeys string Keys for two factor auth (yubico).\nlastname string"} +{"id":"GET /access/users/{userid}/tfa","method":"GET","path":"/access/users/{userid}/tfa","section":"access","summary":"read_user_tfa_type","description":"Get user TFA types (Personal and Realm).","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[{"name":"multiple","type":"boolean","required":false,"description":"Request all entries as an array.","default":0}],"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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify","Sys.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/access/users/{userid}/tfa\naccess\nread_user_tfa_type\nGet user TFA types (Personal and Realm).\nuserid string Full User ID, in the `name@realm` format.\nmultiple boolean Request all entries as an array."} +{"id":"GET /access/users/{userid}/token","method":"GET","path":"/access/users/{userid}/token","section":"access","summary":"token_index","description":"Get user API tokens.","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"GET\n/access/users/{userid}/token\naccess\ntoken_index\nGet user API tokens.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"DELETE /access/users/{userid}/token/{tokenid}","method":"DELETE","path":"/access/users/{userid}/token/{tokenid}","section":"access","summary":"remove_token","description":"Remove API token for a specific user.","pathParameters":[{"name":"tokenid","type":"string","required":true,"description":"User-specific token identifier."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"DELETE\n/access/users/{userid}/token/{tokenid}\naccess\nremove_token\nRemove API token for a specific user.\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"GET /access/users/{userid}/token/{tokenid}","method":"GET","path":"/access/users/{userid}/token/{tokenid}","section":"access","summary":"read_token","description":"Get specific API token information.","pathParameters":[{"name":"tokenid","type":"string","required":true,"description":"User-specific token identifier."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"GET\n/access/users/{userid}/token/{tokenid}\naccess\nread_token\nGet specific API token information.\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"POST /access/users/{userid}/token/{tokenid}","method":"POST","path":"/access/users/{userid}/token/{tokenid}","section":"access","summary":"generate_token","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!","pathParameters":[{"name":"tokenid","type":"string","required":true,"description":"User-specific token identifier."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[{"name":"comment","type":"string","required":false},{"name":"expire","type":"integer","required":false,"description":"API token expiration date (seconds since epoch). '0' means no expiration date.","default":"same as user","minimum":0},{"name":"privsep","type":"boolean","required":false,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","default":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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"POST\n/access/users/{userid}/token/{tokenid}\naccess\ngenerate_token\nGenerate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\nexpire integer API token expiration date (seconds since epoch). '0' means no expiration date.\nprivsep boolean Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user."} +{"id":"PUT /access/users/{userid}/token/{tokenid}","method":"PUT","path":"/access/users/{userid}/token/{tokenid}","section":"access","summary":"update_token_info","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!","pathParameters":[{"name":"tokenid","type":"string","required":true,"description":"User-specific token identifier."},{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[{"name":"comment","type":"string","required":false},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"expire","type":"integer","required":false,"description":"API token expiration date (seconds since epoch). '0' means no expiration date.","default":"same as user","minimum":0},{"name":"privsep","type":"boolean","required":false,"description":"Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.","default":1},{"name":"regenerate","type":"boolean","required":false,"description":"Regenerate the token's secret value. All users of the previous secret will lose access after this operation.","default":0}],"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"},"permissions":{"check":["or",["userid-param","self"],["userid-group",["User.Modify"]]]},"raw":{"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"}},"searchText":"PUT\n/access/users/{userid}/token/{tokenid}\naccess\nupdate_token_info\nUpdate 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!\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\ndelete string A list of settings you want to delete.\nexpire integer API token expiration date (seconds since epoch). '0' means no expiration date.\nprivsep boolean Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.\nregenerate boolean Regenerate the token's secret value. All users of the previous secret will lose access after this operation."} +{"id":"PUT /access/users/{userid}/unlock-tfa","method":"PUT","path":"/access/users/{userid}/unlock-tfa","section":"access","summary":"unlock_tfa","description":"Unlock a user's TFA authentication.","pathParameters":[{"name":"userid","type":"string","required":true,"description":"Full User ID, in the `name@realm` format.","format":"pve-userid"}],"requestParameters":[],"returns":{"type":"boolean"},"permissions":{"check":["userid-group",["User.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/access/users/{userid}/unlock-tfa\naccess\nunlock_tfa\nUnlock a user's TFA authentication.\nuserid string Full User ID, in the `name@realm` format."} +{"id":"POST /access/vncticket","method":"POST","path":"/access/vncticket","section":"access","summary":"verify_vnc_ticket","description":"verify VNC authentication ticket.","pathParameters":[],"requestParameters":[{"name":"authid","type":"string","required":true,"description":"UserId or token"},{"name":"path","type":"string","required":true,"description":"Verify ticket, and check if user have access 'privs' on 'path'"},{"name":"privs","type":"string","required":true,"description":"Verify ticket, and check if user have access 'privs' on 'path'","format":"pve-priv-list"},{"name":"vncticket","type":"string","required":true,"description":"The VNC ticket."},{"name":"port","type":"integer","required":false,"description":"Verify that the ticket is valid for this port."}],"returns":{"type":"null"},"permissions":{"description":"You need to pass valid credientials.","user":"world"},"raw":{"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"}},"searchText":"POST\n/access/vncticket\naccess\nverify_vnc_ticket\nverify VNC authentication ticket.\nauthid string UserId or token\npath string Verify ticket, and check if user have access 'privs' on 'path'\nprivs string Verify ticket, and check if user have access 'privs' on 'path'\nvncticket string The VNC ticket.\nport integer Verify that the ticket is valid for this port."} +{"id":"GET /cluster","method":"GET","path":"/cluster","section":"cluster","summary":"index","description":"Cluster index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster\ncluster\nindex\nCluster index."} +{"id":"GET /cluster/acme","method":"GET","path":"/cluster/acme","section":"cluster","summary":"index","description":"ACMEAccount index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/acme\ncluster\nindex\nACMEAccount index."} +{"id":"GET /cluster/acme/account","method":"GET","path":"/cluster/acme/account","section":"cluster","summary":"account_index","description":"ACMEAccount index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/acme/account\ncluster\naccount_index\nACMEAccount index."} +{"id":"POST /cluster/acme/account","method":"POST","path":"/cluster/acme/account","section":"cluster","summary":"register_account","description":"Register a new ACME account with CA.","pathParameters":[],"requestParameters":[{"name":"contact","type":"string","required":true,"description":"Contact email addresses.","format":"email-list"},{"name":"directory","type":"string","required":false,"description":"URL of ACME CA directory endpoint.","default":"https://acme-v02.api.letsencrypt.org/directory"},{"name":"eab-hmac-key","type":"string","required":false,"description":"HMAC key for External Account Binding."},{"name":"eab-kid","type":"string","required":false,"description":"Key Identifier for External Account Binding."},{"name":"name","type":"string","required":false,"description":"ACME account config file name.","default":"default","format":"pve-configid"},{"name":"tos_url","type":"string","required":false,"description":"URL of CA TermsOfService - setting this indicates agreement."}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"POST\n/cluster/acme/account\ncluster\nregister_account\nRegister a new ACME account with CA.\ncontact string Contact email addresses.\ndirectory string URL of ACME CA directory endpoint.\neab-hmac-key string HMAC key for External Account Binding.\neab-kid string Key Identifier for External Account Binding.\nname string ACME account config file name.\ntos_url string URL of CA TermsOfService - setting this indicates agreement."} +{"id":"DELETE /cluster/acme/account/{name}","method":"DELETE","path":"/cluster/acme/account/{name}","section":"cluster","summary":"deactivate_account","description":"Deactivate existing ACME account at CA.","pathParameters":[{"name":"name","type":"string","required":false,"description":"ACME account config file name.","default":"default","format":"pve-configid"}],"requestParameters":[],"returns":{"type":"string"},"raw":{"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"}},"searchText":"DELETE\n/cluster/acme/account/{name}\ncluster\ndeactivate_account\nDeactivate existing ACME account at CA.\nname string ACME account config file name."} +{"id":"GET /cluster/acme/account/{name}","method":"GET","path":"/cluster/acme/account/{name}","section":"cluster","summary":"get_account","description":"Return existing ACME account information.","pathParameters":[{"name":"name","type":"string","required":false,"description":"ACME account config file name.","default":"default","format":"pve-configid"}],"requestParameters":[],"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"},"raw":{"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"}},"searchText":"GET\n/cluster/acme/account/{name}\ncluster\nget_account\nReturn existing ACME account information.\nname string ACME account config file name."} +{"id":"PUT /cluster/acme/account/{name}","method":"PUT","path":"/cluster/acme/account/{name}","section":"cluster","summary":"update_account","description":"Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.","pathParameters":[{"name":"name","type":"string","required":false,"description":"ACME account config file name.","default":"default","format":"pve-configid"}],"requestParameters":[{"name":"contact","type":"string","required":false,"description":"Contact email addresses.","format":"email-list"}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"PUT\n/cluster/acme/account/{name}\ncluster\nupdate_account\nUpdate existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.\nname string ACME account config file name.\ncontact string Contact email addresses."} +{"id":"GET /cluster/acme/challenge-schema","method":"GET","path":"/cluster/acme/challenge-schema","section":"cluster","summary":"challengeschema","description":"Get schema of ACME challenge types.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/acme/challenge-schema\ncluster\nchallengeschema\nGet schema of ACME challenge types."} +{"id":"GET /cluster/acme/directories","method":"GET","path":"/cluster/acme/directories","section":"cluster","summary":"get_directories","description":"Get named known ACME directory endpoints.","pathParameters":[],"requestParameters":[],"returns":{"items":{"additionalProperties":0,"properties":{"name":{"type":"string"},"url":{"description":"URL of ACME CA directory endpoint.","pattern":"^https?://.*","type":"string"}},"type":"object"},"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/acme/directories\ncluster\nget_directories\nGet named known ACME directory endpoints."} +{"id":"GET /cluster/acme/meta","method":"GET","path":"/cluster/acme/meta","section":"cluster","summary":"get_meta","description":"Retrieve ACME Directory Meta Information","pathParameters":[],"requestParameters":[{"name":"directory","type":"string","required":false,"description":"URL of ACME CA directory endpoint.","default":"https://acme-v02.api.letsencrypt.org/directory"}],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/acme/meta\ncluster\nget_meta\nRetrieve ACME Directory Meta Information\ndirectory string URL of ACME CA directory endpoint."} +{"id":"GET /cluster/acme/plugins","method":"GET","path":"/cluster/acme/plugins","section":"cluster","summary":"index","description":"ACME plugin index.","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list ACME plugins of a specific type","enum":["dns","standalone"]}],"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"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"GET\n/cluster/acme/plugins\ncluster\nindex\nACME plugin index.\ntype string Only list ACME plugins of a specific type dns standalone"} +{"id":"POST /cluster/acme/plugins","method":"POST","path":"/cluster/acme/plugins","section":"cluster","summary":"add_plugin","description":"Add ACME plugin configuration.","pathParameters":[],"requestParameters":[{"name":"id","type":"string","required":true,"description":"ACME Plugin ID name","format":"pve-configid"},{"name":"type","type":"string","required":true,"description":"ACME challenge type.","enum":["dns","standalone"]},{"name":"api","type":"string","required":false,"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"]},{"name":"data","type":"string","required":false,"description":"DNS plugin data. (base64 encoded)"},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable the config."},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"validation-delay","type":"integer","required":false,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","default":30,"minimum":0,"maximum":172800}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/acme/plugins\ncluster\nadd_plugin\nAdd ACME plugin configuration.\nid string ACME Plugin ID name\ntype string ACME challenge type. dns standalone\napi string API plugin name 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\ndata string DNS plugin data. (base64 encoded)\ndisable boolean Flag to disable the config.\nnodes string List of cluster node names.\nvalidation-delay integer Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records."} +{"id":"DELETE /cluster/acme/plugins/{id}","method":"DELETE","path":"/cluster/acme/plugins/{id}","section":"cluster","summary":"delete_plugin","description":"Delete ACME plugin configuration.","pathParameters":[{"name":"id","type":"string","required":true,"description":"Unique identifier for ACME plugin instance.","format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/acme/plugins/{id}\ncluster\ndelete_plugin\nDelete ACME plugin configuration.\nid string Unique identifier for ACME plugin instance."} +{"id":"GET /cluster/acme/plugins/{id}","method":"GET","path":"/cluster/acme/plugins/{id}","section":"cluster","summary":"get_plugin_config","description":"Get ACME plugin configuration.","pathParameters":[{"name":"id","type":"string","required":true,"description":"Unique identifier for ACME plugin instance.","format":"pve-configid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"GET\n/cluster/acme/plugins/{id}\ncluster\nget_plugin_config\nGet ACME plugin configuration.\nid string Unique identifier for ACME plugin instance."} +{"id":"PUT /cluster/acme/plugins/{id}","method":"PUT","path":"/cluster/acme/plugins/{id}","section":"cluster","summary":"update_plugin","description":"Update ACME plugin configuration.","pathParameters":[{"name":"id","type":"string","required":true,"description":"ACME Plugin ID name","format":"pve-configid"}],"requestParameters":[{"name":"api","type":"string","required":false,"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"]},{"name":"data","type":"string","required":false,"description":"DNS plugin data. (base64 encoded)"},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable the config."},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"validation-delay","type":"integer","required":false,"description":"Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records.","default":30,"minimum":0,"maximum":172800}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/acme/plugins/{id}\ncluster\nupdate_plugin\nUpdate ACME plugin configuration.\nid string ACME Plugin ID name\napi string API plugin name 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\ndata string DNS plugin data. (base64 encoded)\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the config.\nnodes string List of cluster node names.\nvalidation-delay integer Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records."} +{"id":"GET /cluster/acme/tos","method":"GET","path":"/cluster/acme/tos","section":"cluster","summary":"get_tos","description":"Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.","pathParameters":[],"requestParameters":[{"name":"directory","type":"string","required":false,"description":"URL of ACME CA directory endpoint.","default":"https://acme-v02.api.letsencrypt.org/directory"}],"returns":{"description":"ACME TermsOfService URL.","optional":1,"type":"string"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/acme/tos\ncluster\nget_tos\nRetrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.\ndirectory string URL of ACME CA directory endpoint."} +{"id":"GET /cluster/backup","method":"GET","path":"/cluster/backup","section":"cluster","summary":"index","description":"List vzdump backup schedule.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/backup\ncluster\nindex\nList vzdump backup schedule."} +{"id":"POST /cluster/backup","method":"POST","path":"/cluster/backup","section":"cluster","summary":"create_job","description":"Create new vzdump backup job.","pathParameters":[],"requestParameters":[{"name":"all","type":"boolean","required":false,"description":"Backup all known guest systems on this host.","default":0},{"name":"bwlimit","type":"integer","required":false,"description":"Limit I/O bandwidth (in KiB/s).","default":0,"minimum":0},{"name":"comment","type":"string","required":false,"description":"Description for the Job."},{"name":"compress","type":"string","required":false,"description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"default":"0"},{"name":"dow","type":"string","required":false,"description":"Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.","default":"mon,tue,wed,thu,fri,sat,sun","format":"pve-day-of-week-list"},{"name":"dumpdir","type":"string","required":false,"description":"Store resulting files to specified directory."},{"name":"enabled","type":"boolean","required":false,"description":"Enable or disable the job.","default":"1"},{"name":"exclude","type":"string","required":false,"description":"Exclude specified guest systems (assumes --all)","format":"pve-vmid-list"},{"name":"exclude-path","type":"array","required":false,"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory."},{"name":"fleecing","type":"string","required":false,"description":"Options for backup fleecing (VM only).","format":"backup-fleecing"},{"name":"id","type":"string","required":false,"description":"Job ID (will be autogenerated).","format":"pve-configid"},{"name":"ionice","type":"integer","required":false,"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.","default":7,"minimum":0,"maximum":8},{"name":"lockwait","type":"integer","required":false,"description":"Maximal time to wait for the global lock (minutes).","default":180,"minimum":0},{"name":"mailnotification","type":"string","required":false,"description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"default":"always"},{"name":"mailto","type":"string","required":false,"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"},{"name":"mode","type":"string","required":false,"description":"Backup mode.","enum":["snapshot","suspend","stop"],"default":"snapshot"},{"name":"node","type":"string","required":false,"description":"Only run if executed on this node.","format":"pve-node"},{"name":"notes-template","type":"string","required":false,"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."},{"name":"notification-mode","type":"string","required":false,"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"],"default":"auto"},{"name":"pbs-change-detection-mode","type":"string","required":false,"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"]},{"name":"performance","type":"string","required":false,"description":"Other performance-related settings.","format":"backup-performance"},{"name":"pigz","type":"integer","required":false,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","default":0},{"name":"pool","type":"string","required":false,"description":"Backup all known guest systems included in the specified pool."},{"name":"protected","type":"boolean","required":false,"description":"If true, mark backup(s) as protected."},{"name":"prune-backups","type":"string","required":false,"description":"Use these retention options instead of those from the storage configuration.","default":"keep-all=1","format":"prune-backups"},{"name":"quiet","type":"boolean","required":false,"description":"Be quiet.","default":0},{"name":"remove","type":"boolean","required":false,"description":"Prune older backups according to 'prune-backups'.","default":1},{"name":"repeat-missed","type":"boolean","required":false,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","default":0},{"name":"schedule","type":"string","required":false,"description":"Backup schedule. The format is a subset of `systemd` calendar events.","format":"pve-calendar-event"},{"name":"script","type":"string","required":false,"description":"Use specified hook script."},{"name":"starttime","type":"string","required":false,"description":"Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used."},{"name":"stdexcludes","type":"boolean","required":false,"description":"Exclude temporary files and logs.","default":1},{"name":"stop","type":"boolean","required":false,"description":"Stop running backup jobs on this host.","default":0},{"name":"stopwait","type":"integer","required":false,"description":"Maximal time to wait until a guest system is stopped (minutes).","default":10,"minimum":0},{"name":"storage","type":"string","required":false,"description":"Store resulting file to this storage.","format":"pve-storage-id"},{"name":"tmpdir","type":"string","required":false,"description":"Store temporary files to specified directory."},{"name":"vmid","type":"string","required":false,"description":"The ID of the guest system you want to backup.","format":"pve-vmid-list"},{"name":"zstd","type":"integer","required":false,"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.","default":1}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user."},"raw":{"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"}},"searchText":"POST\n/cluster/backup\ncluster\ncreate_job\nCreate new vzdump backup job.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncomment string Description for the Job.\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndow string Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.\ndumpdir string Store resulting files to specified directory.\nenabled boolean Enable or disable the job.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nid string Job ID (will be autogenerated).\nionice integer 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnode string Only run if executed on this node.\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nrepeat-missed boolean If true, the job will be run as soon as possible if it was missed while the scheduler was not running.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\nscript string Use specified hook script.\nstarttime string Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.\nstdexcludes boolean Exclude temporary files and logs.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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."} +{"id":"GET /cluster/backup-info","method":"GET","path":"/cluster/backup-info","section":"cluster","summary":"index","description":"Index for backup info related endpoints","pathParameters":[],"requestParameters":[],"returns":{"description":"Directory index.","items":{"properties":{"subdir":{"description":"API sub-directory endpoint","type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"raw":{"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"}},"searchText":"GET\n/cluster/backup-info\ncluster\nindex\nIndex for backup info related endpoints"} +{"id":"GET /cluster/backup-info/not-backed-up","method":"GET","path":"/cluster/backup-info/not-backed-up","section":"cluster","summary":"get_guests_not_in_backup","description":"Shows all guests which are not covered by any backup job.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/backup-info/not-backed-up\ncluster\nget_guests_not_in_backup\nShows all guests which are not covered by any backup job."} +{"id":"DELETE /cluster/backup/{id}","method":"DELETE","path":"/cluster/backup/{id}","section":"cluster","summary":"delete_job","description":"Delete vzdump backup job definition.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The job ID."}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/backup/{id}\ncluster\ndelete_job\nDelete vzdump backup job definition.\nid string The job ID."} +{"id":"GET /cluster/backup/{id}","method":"GET","path":"/cluster/backup/{id}","section":"cluster","summary":"read_job","description":"Read vzdump backup job definition.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The job ID."}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/backup/{id}\ncluster\nread_job\nRead vzdump backup job definition.\nid string The job ID."} +{"id":"PUT /cluster/backup/{id}","method":"PUT","path":"/cluster/backup/{id}","section":"cluster","summary":"update_job","description":"Update vzdump backup job definition.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The job ID."}],"requestParameters":[{"name":"all","type":"boolean","required":false,"description":"Backup all known guest systems on this host.","default":0},{"name":"bwlimit","type":"integer","required":false,"description":"Limit I/O bandwidth (in KiB/s).","default":0,"minimum":0},{"name":"comment","type":"string","required":false,"description":"Description for the Job."},{"name":"compress","type":"string","required":false,"description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"default":"0"},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dow","type":"string","required":false,"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"},{"name":"dumpdir","type":"string","required":false,"description":"Store resulting files to specified directory."},{"name":"enabled","type":"boolean","required":false,"description":"Enable or disable the job.","default":"1"},{"name":"exclude","type":"string","required":false,"description":"Exclude specified guest systems (assumes --all)","format":"pve-vmid-list"},{"name":"exclude-path","type":"array","required":false,"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory."},{"name":"fleecing","type":"string","required":false,"description":"Options for backup fleecing (VM only).","format":"backup-fleecing"},{"name":"ionice","type":"integer","required":false,"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.","default":7,"minimum":0,"maximum":8},{"name":"lockwait","type":"integer","required":false,"description":"Maximal time to wait for the global lock (minutes).","default":180,"minimum":0},{"name":"mailnotification","type":"string","required":false,"description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"default":"always"},{"name":"mailto","type":"string","required":false,"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"},{"name":"mode","type":"string","required":false,"description":"Backup mode.","enum":["snapshot","suspend","stop"],"default":"snapshot"},{"name":"node","type":"string","required":false,"description":"Only run if executed on this node.","format":"pve-node"},{"name":"notes-template","type":"string","required":false,"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."},{"name":"notification-mode","type":"string","required":false,"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"],"default":"auto"},{"name":"pbs-change-detection-mode","type":"string","required":false,"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"]},{"name":"performance","type":"string","required":false,"description":"Other performance-related settings.","format":"backup-performance"},{"name":"pigz","type":"integer","required":false,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","default":0},{"name":"pool","type":"string","required":false,"description":"Backup all known guest systems included in the specified pool."},{"name":"protected","type":"boolean","required":false,"description":"If true, mark backup(s) as protected."},{"name":"prune-backups","type":"string","required":false,"description":"Use these retention options instead of those from the storage configuration.","default":"keep-all=1","format":"prune-backups"},{"name":"quiet","type":"boolean","required":false,"description":"Be quiet.","default":0},{"name":"remove","type":"boolean","required":false,"description":"Prune older backups according to 'prune-backups'.","default":1},{"name":"repeat-missed","type":"boolean","required":false,"description":"If true, the job will be run as soon as possible if it was missed while the scheduler was not running.","default":0},{"name":"schedule","type":"string","required":false,"description":"Backup schedule. The format is a subset of `systemd` calendar events.","format":"pve-calendar-event"},{"name":"script","type":"string","required":false,"description":"Use specified hook script."},{"name":"starttime","type":"string","required":false,"description":"Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used."},{"name":"stdexcludes","type":"boolean","required":false,"description":"Exclude temporary files and logs.","default":1},{"name":"stop","type":"boolean","required":false,"description":"Stop running backup jobs on this host.","default":0},{"name":"stopwait","type":"integer","required":false,"description":"Maximal time to wait until a guest system is stopped (minutes).","default":10,"minimum":0},{"name":"storage","type":"string","required":false,"description":"Store resulting file to this storage.","format":"pve-storage-id"},{"name":"tmpdir","type":"string","required":false,"description":"Store temporary files to specified directory."},{"name":"vmid","type":"string","required":false,"description":"The ID of the guest system you want to backup.","format":"pve-vmid-list"},{"name":"zstd","type":"integer","required":false,"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.","default":1}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user."},"raw":{"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"}},"searchText":"PUT\n/cluster/backup/{id}\ncluster\nupdate_job\nUpdate vzdump backup job definition.\nid string The job ID.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncomment string Description for the Job.\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndelete string A list of settings you want to delete.\ndow string Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.\ndumpdir string Store resulting files to specified directory.\nenabled boolean Enable or disable the job.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nionice integer 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnode string Only run if executed on this node.\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nrepeat-missed boolean If true, the job will be run as soon as possible if it was missed while the scheduler was not running.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\nscript string Use specified hook script.\nstarttime string Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.\nstdexcludes boolean Exclude temporary files and logs.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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."} +{"id":"GET /cluster/backup/{id}/included_volumes","method":"GET","path":"/cluster/backup/{id}/included_volumes","section":"cluster","summary":"get_volume_backup_included","description":"Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The job ID."}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/backup/{id}/included_volumes\ncluster\nget_volume_backup_included\nReturns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.\nid string The job ID."} +{"id":"GET /cluster/bulk-action","method":"GET","path":"/cluster/bulk-action","section":"cluster","summary":"index","description":"List resource types.","pathParameters":[],"requestParameters":[],"returns":{"items":{"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/bulk-action\ncluster\nindex\nList resource types."} +{"id":"GET /cluster/bulk-action/guest","method":"GET","path":"/cluster/bulk-action/guest","section":"cluster","summary":"index","description":"Bulk action index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/bulk-action/guest\ncluster\nindex\nBulk action index."} +{"id":"POST /cluster/bulk-action/guest/migrate","method":"POST","path":"/cluster/bulk-action/guest/migrate","section":"cluster","summary":"migrate","description":"Bulk migrate all guests on the cluster.","pathParameters":[],"requestParameters":[{"name":"target","type":"string","required":true,"description":"Target node.","format":"pve-node"},{"name":"max-workers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently.","default":1,"minimum":1,"maximum":64},{"name":"maxworkers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","default":1,"minimum":1,"maximum":64},{"name":"online","type":"boolean","required":false,"description":"Enable live migration for VMs and restart migration for CTs."},{"name":"vms","type":"array","required":false,"description":"Only consider guests from this list of VMIDs."},{"name":"with-local-disks","type":"boolean","required":false,"description":"Enable live storage migration for local disk"}],"returns":{"description":"UPID of the worker","type":"string"},"permissions":{"description":"The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","user":"all"},"raw":{"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"}},"searchText":"POST\n/cluster/bulk-action/guest/migrate\ncluster\nmigrate\nBulk migrate all guests on the cluster.\ntarget string Target node.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\nonline boolean Enable live migration for VMs and restart migration for CTs.\nvms array Only consider guests from this list of VMIDs.\nwith-local-disks boolean Enable live storage migration for local disk"} +{"id":"POST /cluster/bulk-action/guest/shutdown","method":"POST","path":"/cluster/bulk-action/guest/shutdown","section":"cluster","summary":"shutdown","description":"Bulk shutdown all guests on the cluster.","pathParameters":[],"requestParameters":[{"name":"force-stop","type":"boolean","required":false,"description":"Makes sure the Guest stops after the timeout.","default":1},{"name":"max-workers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently.","default":4,"minimum":1,"maximum":64},{"name":"maxworkers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","default":4,"minimum":1,"maximum":64},{"name":"timeout","type":"integer","required":false,"description":"Default shutdown timeout in seconds if none is configured for the guest.","default":180},{"name":"vms","type":"array","required":false,"description":"Only consider guests from this list of VMIDs."}],"returns":{"description":"UPID of the worker","type":"string"},"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","user":"all"},"raw":{"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"}},"searchText":"POST\n/cluster/bulk-action/guest/shutdown\ncluster\nshutdown\nBulk shutdown all guests on the cluster.\nforce-stop boolean Makes sure the Guest stops after the timeout.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\ntimeout integer Default shutdown timeout in seconds if none is configured for the guest.\nvms array Only consider guests from this list of VMIDs."} +{"id":"POST /cluster/bulk-action/guest/start","method":"POST","path":"/cluster/bulk-action/guest/start","section":"cluster","summary":"start","description":"Bulk start or resume all guests on the cluster.","pathParameters":[],"requestParameters":[{"name":"max-workers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently.","default":4,"minimum":1,"maximum":64},{"name":"maxworkers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","default":4,"minimum":1,"maximum":64},{"name":"timeout","type":"integer","required":false,"description":"Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration)."},{"name":"vms","type":"array","required":false,"description":"Only consider guests from this list of VMIDs."}],"returns":{"description":"UPID of the worker","type":"string"},"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","user":"all"},"raw":{"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"}},"searchText":"POST\n/cluster/bulk-action/guest/start\ncluster\nstart\nBulk start or resume all guests on the cluster.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\ntimeout integer Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration).\nvms array Only consider guests from this list of VMIDs."} +{"id":"POST /cluster/bulk-action/guest/suspend","method":"POST","path":"/cluster/bulk-action/guest/suspend","section":"cluster","summary":"suspend","description":"Bulk suspend all guests on the cluster.","pathParameters":[],"requestParameters":[{"name":"max-workers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently.","default":4,"minimum":1,"maximum":64},{"name":"maxworkers","type":"integer","required":false,"description":"Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.","default":4,"minimum":1,"maximum":64},{"name":"statestorage","type":"string","required":false,"description":"The storage for the VM state.","format":"pve-storage-id"},{"name":"to-disk","type":"boolean","required":false,"description":"If set, suspends the guests to disk. Will be resumed on next start.","default":0},{"name":"vms","type":"array","required":false,"description":"Only consider guests from this list of VMIDs."}],"returns":{"description":"UPID of the worker","type":"string"},"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"},"raw":{"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"}},"searchText":"POST\n/cluster/bulk-action/guest/suspend\ncluster\nsuspend\nBulk suspend all guests on the cluster.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\nstatestorage string The storage for the VM state.\nto-disk boolean If set, suspends the guests to disk. Will be resumed on next start.\nvms array Only consider guests from this list of VMIDs."} +{"id":"GET /cluster/ceph","method":"GET","path":"/cluster/ceph","section":"cluster","summary":"cephindex","description":"Cluster ceph index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/ceph\ncluster\ncephindex\nCluster ceph index."} +{"id":"GET /cluster/ceph/flags","method":"GET","path":"/cluster/ceph/flags","section":"cluster","summary":"get_all_flags","description":"get the status of all ceph flags","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ceph/flags\ncluster\nget_all_flags\nget the status of all ceph flags"} +{"id":"PUT /cluster/ceph/flags","method":"PUT","path":"/cluster/ceph/flags","section":"cluster","summary":"set_flags","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.","pathParameters":[],"requestParameters":[{"name":"nobackfill","type":"boolean","required":false,"description":"Backfilling of PGs is suspended."},{"name":"nodeep-scrub","type":"boolean","required":false,"description":"Deep Scrubbing is disabled."},{"name":"nodown","type":"boolean","required":false,"description":"OSD failure reports are being ignored, such that the monitors will not mark OSDs down."},{"name":"noin","type":"boolean","required":false,"description":"OSDs that were previously marked out will not be marked back in when they start."},{"name":"noout","type":"boolean","required":false,"description":"OSDs will not automatically be marked out after the configured interval."},{"name":"norebalance","type":"boolean","required":false,"description":"Rebalancing of PGs is suspended."},{"name":"norecover","type":"boolean","required":false,"description":"Recovery of PGs is suspended."},{"name":"noscrub","type":"boolean","required":false,"description":"Scrubbing is disabled."},{"name":"notieragent","type":"boolean","required":false,"description":"Cache tiering activity is suspended."},{"name":"noup","type":"boolean","required":false,"description":"OSDs are not allowed to start."},{"name":"pause","type":"boolean","required":false,"description":"Pauses read and writes."}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/ceph/flags\ncluster\nset_flags\nSet/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.\nnobackfill boolean Backfilling of PGs is suspended.\nnodeep-scrub boolean Deep Scrubbing is disabled.\nnodown boolean OSD failure reports are being ignored, such that the monitors will not mark OSDs down.\nnoin boolean OSDs that were previously marked out will not be marked back in when they start.\nnoout boolean OSDs will not automatically be marked out after the configured interval.\nnorebalance boolean Rebalancing of PGs is suspended.\nnorecover boolean Recovery of PGs is suspended.\nnoscrub boolean Scrubbing is disabled.\nnotieragent boolean Cache tiering activity is suspended.\nnoup boolean OSDs are not allowed to start.\npause boolean Pauses read and writes."} +{"id":"GET /cluster/ceph/flags/{flag}","method":"GET","path":"/cluster/ceph/flags/{flag}","section":"cluster","summary":"get_flag","description":"Get the status of a specific ceph flag.","pathParameters":[{"name":"flag","type":"string","required":true,"description":"The name of the flag name to get.","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"]}],"requestParameters":[],"returns":{"type":"boolean"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ceph/flags/{flag}\ncluster\nget_flag\nGet the status of a specific ceph flag.\nflag string The name of the flag name to get. nobackfill nodeep-scrub nodown noin noout norebalance norecover noscrub notieragent noup pause"} +{"id":"PUT /cluster/ceph/flags/{flag}","method":"PUT","path":"/cluster/ceph/flags/{flag}","section":"cluster","summary":"update_flag","description":"Set or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task).","pathParameters":[{"name":"flag","type":"string","required":true,"description":"The ceph flag to update","enum":["nobackfill","nodeep-scrub","nodown","noin","noout","norebalance","norecover","noscrub","notieragent","noup","pause"]}],"requestParameters":[{"name":"value","type":"boolean","required":true,"description":"The new value of the flag"}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/ceph/flags/{flag}\ncluster\nupdate_flag\nSet or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task).\nflag string The ceph flag to update nobackfill nodeep-scrub nodown noin noout norebalance norecover noscrub notieragent noup pause\nvalue boolean The new value of the flag"} +{"id":"GET /cluster/ceph/metadata","method":"GET","path":"/cluster/ceph/metadata","section":"cluster","summary":"metadata","description":"Get ceph metadata.","pathParameters":[],"requestParameters":[{"name":"scope","type":"string","required":false,"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"],"default":"all"}],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/cluster/ceph/metadata\ncluster\nmetadata\nGet ceph metadata.\nscope string 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. all versions"} +{"id":"GET /cluster/ceph/status","method":"GET","path":"/cluster/ceph/status","section":"cluster","summary":"status","description":"Get ceph status.","pathParameters":[],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/cluster/ceph/status\ncluster\nstatus\nGet ceph status."} +{"id":"GET /cluster/config","method":"GET","path":"/cluster/config","section":"cluster","summary":"index","description":"Directory index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/config\ncluster\nindex\nDirectory index."} +{"id":"POST /cluster/config","method":"POST","path":"/cluster/config","section":"cluster","summary":"create","description":"Generate new cluster configuration. If no links given, default to local IP address as link0.","pathParameters":[],"requestParameters":[{"name":"clustername","type":"string","required":true,"description":"The name of the cluster.","format":"pve-node"},{"name":"link[n]","type":"string","required":false,"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)"},{"name":"nodeid","type":"integer","required":false,"description":"Node id for this node.","minimum":1},{"name":"token-coefficient","type":"integer","required":false,"description":"Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details.","default":125,"minimum":0},{"name":"votes","type":"integer","required":false,"description":"Number of votes for this node.","minimum":1}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"POST\n/cluster/config\ncluster\ncreate\nGenerate new cluster configuration. If no links given, default to local IP address as link0.\nclustername string The name of the cluster.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnodeid integer Node id for this node.\ntoken-coefficient integer Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details.\nvotes integer Number of votes for this node."} +{"id":"GET /cluster/config/apiversion","method":"GET","path":"/cluster/config/apiversion","section":"cluster","summary":"join_api_version","description":"Return the version of the cluster join API available on this node.","pathParameters":[],"requestParameters":[],"returns":{"description":"Cluster Join API version, currently 1","minimum":0,"type":"integer"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/config/apiversion\ncluster\njoin_api_version\nReturn the version of the cluster join API available on this node."} +{"id":"GET /cluster/config/join","method":"GET","path":"/cluster/config/join","section":"cluster","summary":"join_info","description":"Get information needed to join this cluster over the connected node.","pathParameters":[],"requestParameters":[{"name":"node","type":"string","required":false,"description":"The node for which the joinee gets the nodeinfo.","default":"current connected node","format":"pve-node"}],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/config/join\ncluster\njoin_info\nGet information needed to join this cluster over the connected node.\nnode string The node for which the joinee gets the nodeinfo."} +{"id":"POST /cluster/config/join","method":"POST","path":"/cluster/config/join","section":"cluster","summary":"join","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).","pathParameters":[],"requestParameters":[{"name":"fingerprint","type":"string","required":true,"description":"Certificate SHA 256 fingerprint."},{"name":"hostname","type":"string","required":true,"description":"Hostname (or IP) of an existing cluster member."},{"name":"password","type":"string","required":true,"description":"Superuser (root) password of peer node."},{"name":"force","type":"boolean","required":false,"description":"Do not throw error if node already exists."},{"name":"link[n]","type":"string","required":false,"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)"},{"name":"nodeid","type":"integer","required":false,"description":"Node id for this node.","minimum":1},{"name":"votes","type":"integer","required":false,"description":"Number of votes for this node","minimum":0}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"POST\n/cluster/config/join\ncluster\njoin\nJoins 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).\nfingerprint string Certificate SHA 256 fingerprint.\nhostname string Hostname (or IP) of an existing cluster member.\npassword string Superuser (root) password of peer node.\nforce boolean Do not throw error if node already exists.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnodeid integer Node id for this node.\nvotes integer Number of votes for this node"} +{"id":"GET /cluster/config/nodes","method":"GET","path":"/cluster/config/nodes","section":"cluster","summary":"nodes","description":"Corosync node list.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"node":{"type":"string"}},"type":"object"},"links":[{"href":"{node}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/config/nodes\ncluster\nnodes\nCorosync node list."} +{"id":"DELETE /cluster/config/nodes/{node}","method":"DELETE","path":"/cluster/config/nodes/{node}","section":"cluster","summary":"delnode","description":"Removes a node from the cluster configuration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"null"},"raw":{"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"}},"searchText":"DELETE\n/cluster/config/nodes/{node}\ncluster\ndelnode\nRemoves a node from the cluster configuration.\nnode string The cluster node name."} +{"id":"POST /cluster/config/nodes/{node}","method":"POST","path":"/cluster/config/nodes/{node}","section":"cluster","summary":"addnode","description":"Adds a node to the cluster configuration. This call is for internal use.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"apiversion","type":"integer","required":false,"description":"The JOIN_API_VERSION of the new node."},{"name":"force","type":"boolean","required":false,"description":"Do not throw error if node already exists."},{"name":"link[n]","type":"string","required":false,"description":"Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)"},{"name":"new_node_ip","type":"string","required":false,"description":"IP Address of node to add. Used as fallback if no links are given.","format":"ip"},{"name":"nodeid","type":"integer","required":false,"description":"Node id for this node.","minimum":1},{"name":"votes","type":"integer","required":false,"description":"Number of votes for this node","minimum":0}],"returns":{"properties":{"corosync_authkey":{"type":"string"},"corosync_conf":{"type":"string"},"warnings":{"items":{"type":"string"},"type":"array"}},"type":"object"},"raw":{"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"}},"searchText":"POST\n/cluster/config/nodes/{node}\ncluster\naddnode\nAdds a node to the cluster configuration. This call is for internal use.\nnode string The cluster node name.\napiversion integer The JOIN_API_VERSION of the new node.\nforce boolean Do not throw error if node already exists.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnew_node_ip string IP Address of node to add. Used as fallback if no links are given.\nnodeid integer Node id for this node.\nvotes integer Number of votes for this node"} +{"id":"GET /cluster/config/qdevice","method":"GET","path":"/cluster/config/qdevice","section":"cluster","summary":"status","description":"Get QDevice status","pathParameters":[],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"allowtoken":1,"description":"Get QDevice status","method":"GET","name":"status","parameters":{"additionalProperties":0},"permissions":{"check":["perm","/",["Sys.Audit"]]},"protected":1,"returns":{"type":"object"}},"searchText":"GET\n/cluster/config/qdevice\ncluster\nstatus\nGet QDevice status"} +{"id":"GET /cluster/config/totem","method":"GET","path":"/cluster/config/totem","section":"cluster","summary":"totem","description":"Get corosync totem protocol settings.","pathParameters":[],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"allowtoken":1,"description":"Get corosync totem protocol settings.","method":"GET","name":"totem","parameters":{"additionalProperties":0},"permissions":{"check":["perm","/",["Sys.Audit"]]},"returns":{"type":"object"}},"searchText":"GET\n/cluster/config/totem\ncluster\ntotem\nGet corosync totem protocol settings."} +{"id":"GET /cluster/firewall","method":"GET","path":"/cluster/firewall","section":"cluster","summary":"index","description":"Directory index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/firewall\ncluster\nindex\nDirectory index."} +{"id":"GET /cluster/firewall/aliases","method":"GET","path":"/cluster/firewall/aliases","section":"cluster","summary":"get_aliases","description":"List aliases","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/aliases\ncluster\nget_aliases\nList aliases"} +{"id":"POST /cluster/firewall/aliases","method":"POST","path":"/cluster/firewall/aliases","section":"cluster","summary":"create_alias","description":"Create IP or Network Alias.","pathParameters":[],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDR"},{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"comment","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/firewall/aliases\ncluster\ncreate_alias\nCreate IP or Network Alias.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string"} +{"id":"DELETE /cluster/firewall/aliases/{name}","method":"DELETE","path":"/cluster/firewall/aliases/{name}","section":"cluster","summary":"remove_alias","description":"Remove IP or Network alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/firewall/aliases/{name}\ncluster\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /cluster/firewall/aliases/{name}","method":"GET","path":"/cluster/firewall/aliases/{name}","section":"cluster","summary":"read_alias","description":"Read alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/aliases/{name}\ncluster\nread_alias\nRead alias.\nname string Alias name."} +{"id":"PUT /cluster/firewall/aliases/{name}","method":"PUT","path":"/cluster/firewall/aliases/{name}","section":"cluster","summary":"update_alias","description":"Update IP or Network alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDR"},{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"rename","type":"string","required":false,"description":"Rename an existing alias."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/firewall/aliases/{name}\ncluster\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias."} +{"id":"GET /cluster/firewall/groups","method":"GET","path":"/cluster/firewall/groups","section":"cluster","summary":"list_security_groups","description":"List security groups.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/groups\ncluster\nlist_security_groups\nList security groups."} +{"id":"POST /cluster/firewall/groups","method":"POST","path":"/cluster/firewall/groups","section":"cluster","summary":"create_security_group","description":"Create new security group.","pathParameters":[],"requestParameters":[{"name":"group","type":"string","required":true,"description":"Security Group name."},{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"rename","type":"string","required":false,"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."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/firewall/groups\ncluster\ncreate_security_group\nCreate new security group.\ngroup string Security Group name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group."} +{"id":"DELETE /cluster/firewall/groups/{group}","method":"DELETE","path":"/cluster/firewall/groups/{group}","section":"cluster","summary":"delete_security_group","description":"Delete security group.","pathParameters":[{"name":"group","type":"string","required":true,"description":"Security Group name."}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/firewall/groups/{group}\ncluster\ndelete_security_group\nDelete security group.\ngroup string Security Group name."} +{"id":"GET /cluster/firewall/groups/{group}","method":"GET","path":"/cluster/firewall/groups/{group}","section":"cluster","summary":"get_rules","description":"List rules.","pathParameters":[{"name":"group","type":"string","required":true,"description":"Security Group name."}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/groups/{group}\ncluster\nget_rules\nList rules.\ngroup string Security Group name."} +{"id":"POST /cluster/firewall/groups/{group}","method":"POST","path":"/cluster/firewall/groups/{group}","section":"cluster","summary":"create_rule","description":"Create new rule.","pathParameters":[{"name":"group","type":"string","required":true,"description":"Security Group name."}],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"type","type":"string","required":true,"description":"Rule type.","enum":["in","out","forward","group"]},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/firewall/groups/{group}\ncluster\ncreate_rule\nCreate new rule.\ngroup string Security Group name.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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."} +{"id":"DELETE /cluster/firewall/groups/{group}/{pos}","method":"DELETE","path":"/cluster/firewall/groups/{group}/{pos}","section":"cluster","summary":"delete_rule","description":"Delete rule.","pathParameters":[{"name":"group","type":"string","required":true,"description":"Security Group name."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/firewall/groups/{group}/{pos}\ncluster\ndelete_rule\nDelete rule.\ngroup string Security Group name.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /cluster/firewall/groups/{group}/{pos}","method":"GET","path":"/cluster/firewall/groups/{group}/{pos}","section":"cluster","summary":"get_rule","description":"Get single rule data.","pathParameters":[{"name":"group","type":"string","required":true,"description":"Security Group name."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/groups/{group}/{pos}\ncluster\nget_rule\nGet single rule data.\ngroup string Security Group name.\npos integer Update rule at position ."} +{"id":"PUT /cluster/firewall/groups/{group}/{pos}","method":"PUT","path":"/cluster/firewall/groups/{group}/{pos}","section":"cluster","summary":"update_rule","description":"Modify rule data.","pathParameters":[{"name":"group","type":"string","required":true,"description":"Security Group name."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"action","type":"string","required":false,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"moveto","type":"integer","required":false,"description":"Move rule to new position . Other arguments are ignored.","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"},{"name":"type","type":"string","required":false,"description":"Rule type.","enum":["in","out","forward","group"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/firewall/groups/{group}/{pos}\ncluster\nupdate_rule\nModify rule data.\ngroup string Security Group name.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group"} +{"id":"GET /cluster/firewall/ipset","method":"GET","path":"/cluster/firewall/ipset","section":"cluster","summary":"ipset_index","description":"List IPSets","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/ipset\ncluster\nipset_index\nList IPSets"} +{"id":"POST /cluster/firewall/ipset","method":"POST","path":"/cluster/firewall/ipset","section":"cluster","summary":"create_ipset","description":"Create new IPSet","pathParameters":[],"requestParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"rename","type":"string","required":false,"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/firewall/ipset\ncluster\ncreate_ipset\nCreate new IPSet\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet."} +{"id":"DELETE /cluster/firewall/ipset/{name}","method":"DELETE","path":"/cluster/firewall/ipset/{name}","section":"cluster","summary":"delete_ipset","description":"Delete IPSet","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Delete all members of the IPSet, if there are any."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/firewall/ipset/{name}\ncluster\ndelete_ipset\nDelete IPSet\nname string IP set name.\nforce boolean Delete all members of the IPSet, if there are any."} +{"id":"GET /cluster/firewall/ipset/{name}","method":"GET","path":"/cluster/firewall/ipset/{name}","section":"cluster","summary":"get_ipset","description":"List IPSet content","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/ipset/{name}\ncluster\nget_ipset\nList IPSet content\nname string IP set name."} +{"id":"POST /cluster/firewall/ipset/{name}","method":"POST","path":"/cluster/firewall/ipset/{name}","section":"cluster","summary":"create_ip","description":"Add IP or Network to IPSet.","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"comment","type":"string","required":false},{"name":"nomatch","type":"boolean","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/firewall/ipset/{name}\ncluster\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean"} +{"id":"DELETE /cluster/firewall/ipset/{name}/{cidr}","method":"DELETE","path":"/cluster/firewall/ipset/{name}/{cidr}","section":"cluster","summary":"remove_ip","description":"Remove IP or Network from IPSet.","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /cluster/firewall/ipset/{name}/{cidr}","method":"GET","path":"/cluster/firewall/ipset/{name}/{cidr}","section":"cluster","summary":"read_ip","description":"Read IP or Network settings from IPSet.","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name."} +{"id":"PUT /cluster/firewall/ipset/{name}/{cidr}","method":"PUT","path":"/cluster/firewall/ipset/{name}/{cidr}","section":"cluster","summary":"update_ip","description":"Update IP or Network settings","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."}],"requestParameters":[{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"nomatch","type":"boolean","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean"} +{"id":"GET /cluster/firewall/macros","method":"GET","path":"/cluster/firewall/macros","section":"cluster","summary":"get_macros","description":"List available macros","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"descr":{"description":"More verbose description (if available).","type":"string"},"macro":{"description":"Macro name.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/macros\ncluster\nget_macros\nList available macros"} +{"id":"GET /cluster/firewall/options","method":"GET","path":"/cluster/firewall/options","section":"cluster","summary":"get_options","description":"Get Firewall options.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/options\ncluster\nget_options\nGet Firewall options."} +{"id":"PUT /cluster/firewall/options","method":"PUT","path":"/cluster/firewall/options","section":"cluster","summary":"set_options","description":"Set Firewall options.","pathParameters":[],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"ebtables","type":"boolean","required":false,"description":"Enable ebtables rules cluster wide.","default":1},{"name":"enable","type":"integer","required":false,"description":"Enable or disable the firewall cluster wide.","default":0,"minimum":0},{"name":"log_ratelimit","type":"string","required":false,"description":"Log ratelimiting settings"},{"name":"policy_forward","type":"string","required":false,"description":"Forward policy.","enum":["ACCEPT","DROP"]},{"name":"policy_in","type":"string","required":false,"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"]},{"name":"policy_out","type":"string","required":false,"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/firewall/options\ncluster\nset_options\nSet Firewall options.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nebtables boolean Enable ebtables rules cluster wide.\nenable integer Enable or disable the firewall cluster wide.\nlog_ratelimit string Log ratelimiting settings\npolicy_forward string Forward policy. ACCEPT DROP\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP"} +{"id":"GET /cluster/firewall/refs","method":"GET","path":"/cluster/firewall/refs","section":"cluster","summary":"refs","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list references of specified type.","enum":["alias","ipset"]}],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/refs\ncluster\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\ntype string Only list references of specified type. alias ipset"} +{"id":"GET /cluster/firewall/rules","method":"GET","path":"/cluster/firewall/rules","section":"cluster","summary":"get_rules","description":"List rules.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/rules\ncluster\nget_rules\nList rules."} +{"id":"POST /cluster/firewall/rules","method":"POST","path":"/cluster/firewall/rules","section":"cluster","summary":"create_rule","description":"Create new rule.","pathParameters":[],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"type","type":"string","required":true,"description":"Rule type.","enum":["in","out","forward","group"]},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/firewall/rules\ncluster\ncreate_rule\nCreate new rule.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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."} +{"id":"DELETE /cluster/firewall/rules/{pos}","method":"DELETE","path":"/cluster/firewall/rules/{pos}","section":"cluster","summary":"delete_rule","description":"Delete rule.","pathParameters":[{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/firewall/rules/{pos}\ncluster\ndelete_rule\nDelete rule.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /cluster/firewall/rules/{pos}","method":"GET","path":"/cluster/firewall/rules/{pos}","section":"cluster","summary":"get_rule","description":"Get single rule data.","pathParameters":[{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/firewall/rules/{pos}\ncluster\nget_rule\nGet single rule data.\npos integer Update rule at position ."} +{"id":"PUT /cluster/firewall/rules/{pos}","method":"PUT","path":"/cluster/firewall/rules/{pos}","section":"cluster","summary":"update_rule","description":"Modify rule data.","pathParameters":[{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"action","type":"string","required":false,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"moveto","type":"integer","required":false,"description":"Move rule to new position . Other arguments are ignored.","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"},{"name":"type","type":"string","required":false,"description":"Rule type.","enum":["in","out","forward","group"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/firewall/rules/{pos}\ncluster\nupdate_rule\nModify rule data.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group"} +{"id":"GET /cluster/ha","method":"GET","path":"/cluster/ha","section":"cluster","summary":"index","description":"Directory index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"id":{"type":"string"}},"type":"object"},"links":[{"href":"{id}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha\ncluster\nindex\nDirectory index."} +{"id":"GET /cluster/ha/groups","method":"GET","path":"/cluster/ha/groups","section":"cluster","summary":"index","description":"Get HA groups. (deprecated in favor of HA rules)","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"group":{"type":"string"}},"type":"object"},"links":[{"href":"{group}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha/groups\ncluster\nindex\nGet HA groups. (deprecated in favor of HA rules)"} +{"id":"POST /cluster/ha/groups","method":"POST","path":"/cluster/ha/groups","section":"cluster","summary":"create","description":"Create a new HA group. (deprecated in favor of HA rules)","pathParameters":[],"requestParameters":[{"name":"group","type":"string","required":true,"description":"The HA group identifier.","format":"pve-configid"},{"name":"nodes","type":"string","required":true,"description":"List of cluster node names with optional priority.","format":"pve-ha-node-list"},{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"nofailback","type":"boolean","required":false,"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.","default":0},{"name":"restricted","type":"boolean","required":false,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","default":0},{"name":"type","type":"string","required":false,"description":"Group type.","enum":["group"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"POST\n/cluster/ha/groups\ncluster\ncreate\nCreate a new HA group. (deprecated in favor of HA rules)\ngroup string The HA group identifier.\nnodes string List of cluster node names with optional priority.\ncomment string Description.\nnofailback boolean 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.\nrestricted boolean Resources bound to restricted groups may only run on nodes defined by the group.\ntype string Group type. group"} +{"id":"DELETE /cluster/ha/groups/{group}","method":"DELETE","path":"/cluster/ha/groups/{group}","section":"cluster","summary":"delete","description":"Delete ha group configuration. (deprecated in favor of HA rules)","pathParameters":[{"name":"group","type":"string","required":true,"description":"The HA group identifier.","format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/ha/groups/{group}\ncluster\ndelete\nDelete ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier."} +{"id":"GET /cluster/ha/groups/{group}","method":"GET","path":"/cluster/ha/groups/{group}","section":"cluster","summary":"read","description":"Read ha group configuration. (deprecated in favor of HA rules)","pathParameters":[{"name":"group","type":"string","required":true,"description":"The HA group identifier.","format":"pve-configid"}],"requestParameters":[],"returns":{},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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":{}},"searchText":"GET\n/cluster/ha/groups/{group}\ncluster\nread\nRead ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier."} +{"id":"PUT /cluster/ha/groups/{group}","method":"PUT","path":"/cluster/ha/groups/{group}","section":"cluster","summary":"update","description":"Update ha group configuration. (deprecated in favor of HA rules)","pathParameters":[{"name":"group","type":"string","required":true,"description":"The HA group identifier.","format":"pve-configid"}],"requestParameters":[{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names with optional priority.","format":"pve-ha-node-list"},{"name":"nofailback","type":"boolean","required":false,"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.","default":0},{"name":"restricted","type":"boolean","required":false,"description":"Resources bound to restricted groups may only run on nodes defined by the group.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/ha/groups/{group}\ncluster\nupdate\nUpdate ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier.\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnodes string List of cluster node names with optional priority.\nnofailback boolean 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.\nrestricted boolean Resources bound to restricted groups may only run on nodes defined by the group."} +{"id":"GET /cluster/ha/resources","method":"GET","path":"/cluster/ha/resources","section":"cluster","summary":"index","description":"List HA resources.","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list resources of specific type","enum":["ct","vm"]}],"returns":{"items":{"properties":{"sid":{"type":"string"}},"type":"object"},"links":[{"href":"{sid}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha/resources\ncluster\nindex\nList HA resources.\ntype string Only list resources of specific type ct vm"} +{"id":"POST /cluster/ha/resources","method":"POST","path":"/cluster/ha/resources","section":"cluster","summary":"create","description":"Create a new HA resource.","pathParameters":[],"requestParameters":[{"name":"sid","type":"string","required":true,"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"},{"name":"auto-rebalance","type":"boolean","required":false,"description":"HA resource may be migrated during automatic rebalancing","default":1},{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"failback","type":"boolean","required":false,"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.","default":1},{"name":"group","type":"string","required":false,"description":"The HA group identifier.","format":"pve-configid"},{"name":"max_relocate","type":"integer","required":false,"description":"Maximal number of resource relocate tries when a resource fails to start.","default":1,"minimum":0},{"name":"max_restart","type":"integer","required":false,"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.","default":1,"minimum":0},{"name":"state","type":"string","required":false,"description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"default":"started"},{"name":"type","type":"string","required":false,"description":"Resource type.","enum":["ct","vm"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"POST\n/cluster/ha/resources\ncluster\ncreate\nCreate a new HA resource.\nsid string 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).\nauto-rebalance boolean HA resource may be migrated during automatic rebalancing\ncomment string Description.\nfailback boolean 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.\ngroup string The HA group identifier.\nmax_relocate integer Maximal number of resource relocate tries when a resource fails to start.\nmax_restart integer 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.\nstate string Requested resource state. started stopped enabled disabled ignored\ntype string Resource type. ct vm"} +{"id":"DELETE /cluster/ha/resources/{sid}","method":"DELETE","path":"/cluster/ha/resources/{sid}","section":"cluster","summary":"delete","description":"Delete resource configuration.","pathParameters":[{"name":"sid","type":"string","required":true,"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"}],"requestParameters":[{"name":"purge","type":"boolean","required":false,"description":"Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule","default":1}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/ha/resources/{sid}\ncluster\ndelete\nDelete resource configuration.\nsid string 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).\npurge boolean Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule"} +{"id":"GET /cluster/ha/resources/{sid}","method":"GET","path":"/cluster/ha/resources/{sid}","section":"cluster","summary":"read","description":"Read resource configuration.","pathParameters":[{"name":"sid","type":"string","required":true,"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"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha/resources/{sid}\ncluster\nread\nRead resource configuration.\nsid string 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)."} +{"id":"PUT /cluster/ha/resources/{sid}","method":"PUT","path":"/cluster/ha/resources/{sid}","section":"cluster","summary":"update","description":"Update resource configuration.","pathParameters":[{"name":"sid","type":"string","required":true,"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"}],"requestParameters":[{"name":"auto-rebalance","type":"boolean","required":false,"description":"HA resource may be migrated during automatic rebalancing","default":1},{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"failback","type":"boolean","required":false,"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.","default":1},{"name":"group","type":"string","required":false,"description":"The HA group identifier.","format":"pve-configid"},{"name":"max_relocate","type":"integer","required":false,"description":"Maximal number of resource relocate tries when a resource fails to start.","default":1,"minimum":0},{"name":"max_restart","type":"integer","required":false,"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.","default":1,"minimum":0},{"name":"state","type":"string","required":false,"description":"Requested resource state.","enum":["started","stopped","enabled","disabled","ignored"],"default":"started"}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/ha/resources/{sid}\ncluster\nupdate\nUpdate resource configuration.\nsid string 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).\nauto-rebalance boolean HA resource may be migrated during automatic rebalancing\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfailback boolean 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.\ngroup string The HA group identifier.\nmax_relocate integer Maximal number of resource relocate tries when a resource fails to start.\nmax_restart integer 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.\nstate string Requested resource state. started stopped enabled disabled ignored"} +{"id":"POST /cluster/ha/resources/{sid}/migrate","method":"POST","path":"/cluster/ha/resources/{sid}/migrate","section":"cluster","summary":"migrate","description":"Request resource migration (online) to another node.","pathParameters":[{"name":"sid","type":"string","required":true,"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"}],"requestParameters":[{"name":"node","type":"string","required":true,"description":"Target node.","format":"pve-node"}],"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"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"POST\n/cluster/ha/resources/{sid}/migrate\ncluster\nmigrate\nRequest resource migration (online) to another node.\nsid string 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).\nnode string Target node."} +{"id":"POST /cluster/ha/resources/{sid}/relocate","method":"POST","path":"/cluster/ha/resources/{sid}/relocate","section":"cluster","summary":"relocate","description":"Request resource relocation to another node. This stops the service on the old node, and restarts it on the target node.","pathParameters":[{"name":"sid","type":"string","required":true,"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"}],"requestParameters":[{"name":"node","type":"string","required":true,"description":"Target node.","format":"pve-node"}],"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"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"POST\n/cluster/ha/resources/{sid}/relocate\ncluster\nrelocate\nRequest resource relocation to another node. This stops the service on the old node, and restarts it on the target node.\nsid string 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).\nnode string Target node."} +{"id":"GET /cluster/ha/rules","method":"GET","path":"/cluster/ha/rules","section":"cluster","summary":"index","description":"Get HA rules.","pathParameters":[],"requestParameters":[{"name":"resource","type":"string","required":false,"description":"Limit the returned list to rules affecting the specified resource."},{"name":"type","type":"string","required":false,"description":"Limit the returned list to the specified rule type.","enum":["node-affinity","resource-affinity"]}],"returns":{"items":{"links":[{"href":"{rule}","rel":"child"}],"properties":{"rule":{"type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha/rules\ncluster\nindex\nGet HA rules.\nresource string Limit the returned list to rules affecting the specified resource.\ntype string Limit the returned list to the specified rule type. node-affinity resource-affinity"} +{"id":"POST /cluster/ha/rules","method":"POST","path":"/cluster/ha/rules","section":"cluster","summary":"create_rule","description":"Create HA rule.","pathParameters":[],"requestParameters":[{"name":"resources","type":"string","required":true,"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"},{"name":"rule","type":"string","required":true,"description":"HA rule identifier.","format":"pve-configid"},{"name":"type","type":"string","required":true,"description":"HA rule type.","enum":["node-affinity","resource-affinity"]},{"name":"affinity","type":"string","required":false,"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"]},{"name":"comment","type":"string","required":false,"description":"HA rule description."},{"name":"disable","type":"boolean","required":false,"description":"Whether the HA rule is disabled."},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names with optional priority.","format":"pve-ha-node-list"},{"name":"strict","type":"boolean","required":false,"description":"Describes whether the node affinity rule is strict or non-strict.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"POST\n/cluster/ha/rules\ncluster\ncreate_rule\nCreate HA rule.\nresources string 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).\nrule string HA rule identifier.\ntype string HA rule type. node-affinity resource-affinity\naffinity string 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'). positive negative\ncomment string HA rule description.\ndisable boolean Whether the HA rule is disabled.\nnodes string List of cluster node names with optional priority.\nstrict boolean Describes whether the node affinity rule is strict or non-strict."} +{"id":"DELETE /cluster/ha/rules/{rule}","method":"DELETE","path":"/cluster/ha/rules/{rule}","section":"cluster","summary":"delete_rule","description":"Delete HA rule.","pathParameters":[{"name":"rule","type":"string","required":true,"description":"HA rule identifier.","format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/ha/rules/{rule}\ncluster\ndelete_rule\nDelete HA rule.\nrule string HA rule identifier."} +{"id":"GET /cluster/ha/rules/{rule}","method":"GET","path":"/cluster/ha/rules/{rule}","section":"cluster","summary":"read_rule","description":"Read HA rule.","pathParameters":[{"name":"rule","type":"string","required":true,"description":"HA rule identifier.","format":"pve-configid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha/rules/{rule}\ncluster\nread_rule\nRead HA rule.\nrule string HA rule identifier."} +{"id":"PUT /cluster/ha/rules/{rule}","method":"PUT","path":"/cluster/ha/rules/{rule}","section":"cluster","summary":"update_rule","description":"Update HA rule.","pathParameters":[{"name":"rule","type":"string","required":true,"description":"HA rule identifier.","format":"pve-configid"}],"requestParameters":[{"name":"type","type":"string","required":true,"description":"HA rule type.","enum":["node-affinity","resource-affinity"]},{"name":"affinity","type":"string","required":false,"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"]},{"name":"comment","type":"string","required":false,"description":"HA rule description."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Whether the HA rule is disabled."},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names with optional priority.","format":"pve-ha-node-list"},{"name":"resources","type":"string","required":false,"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"},{"name":"strict","type":"boolean","required":false,"description":"Describes whether the node affinity rule is strict or non-strict.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/ha/rules/{rule}\ncluster\nupdate_rule\nUpdate HA rule.\nrule string HA rule identifier.\ntype string HA rule type. node-affinity resource-affinity\naffinity string 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'). positive negative\ncomment string HA rule description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Whether the HA rule is disabled.\nnodes string List of cluster node names with optional priority.\nresources string 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).\nstrict boolean Describes whether the node affinity rule is strict or non-strict."} +{"id":"GET /cluster/ha/status","method":"GET","path":"/cluster/ha/status","section":"cluster","summary":"index","description":"Directory index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/ha/status\ncluster\nindex\nDirectory index."} +{"id":"POST /cluster/ha/status/arm-ha","method":"POST","path":"/cluster/ha/status/arm-ha","section":"cluster","summary":"arm-ha","description":"Request re-arming the HA stack after it was disarmed.","pathParameters":[],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"POST\n/cluster/ha/status/arm-ha\ncluster\narm-ha\nRequest re-arming the HA stack after it was disarmed."} +{"id":"GET /cluster/ha/status/current","method":"GET","path":"/cluster/ha/status/current","section":"cluster","summary":"status","description":"Get HA manager status.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha/status/current\ncluster\nstatus\nGet HA manager status."} +{"id":"POST /cluster/ha/status/disarm-ha","method":"POST","path":"/cluster/ha/status/disarm-ha","section":"cluster","summary":"disarm-ha","description":"Request disarming the HA stack, releasing all watchdogs cluster-wide.","pathParameters":[],"requestParameters":[{"name":"resource-mode","type":"string","required":true,"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"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Console"]]},"raw":{"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"}},"searchText":"POST\n/cluster/ha/status/disarm-ha\ncluster\ndisarm-ha\nRequest disarming the HA stack, releasing all watchdogs cluster-wide.\nresource-mode string 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. freeze ignore"} +{"id":"GET /cluster/ha/status/manager_status","method":"GET","path":"/cluster/ha/status/manager_status","section":"cluster","summary":"manager_status","description":"Get full HA manager status, including LRM status.","pathParameters":[],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/ha/status/manager_status\ncluster\nmanager_status\nGet full HA manager status, including LRM status."} +{"id":"GET /cluster/jobs","method":"GET","path":"/cluster/jobs","section":"cluster","summary":"index","description":"Index for jobs related endpoints.","pathParameters":[],"requestParameters":[],"returns":{"description":"Directory index.","items":{"properties":{"subdir":{"description":"API sub-directory endpoint","type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/jobs\ncluster\nindex\nIndex for jobs related endpoints."} +{"id":"GET /cluster/jobs/realm-sync","method":"GET","path":"/cluster/jobs/realm-sync","section":"cluster","summary":"syncjob_index","description":"List configured realm-sync-jobs.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/jobs/realm-sync\ncluster\nsyncjob_index\nList configured realm-sync-jobs."} +{"id":"DELETE /cluster/jobs/realm-sync/{id}","method":"DELETE","path":"/cluster/jobs/realm-sync/{id}","section":"cluster","summary":"delete_job","description":"Delete realm-sync job definition.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/jobs/realm-sync/{id}\ncluster\ndelete_job\nDelete realm-sync job definition.\nid string"} +{"id":"GET /cluster/jobs/realm-sync/{id}","method":"GET","path":"/cluster/jobs/realm-sync/{id}","section":"cluster","summary":"read_job","description":"Read realm-sync job definition.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/jobs/realm-sync/{id}\ncluster\nread_job\nRead realm-sync job definition.\nid string"} +{"id":"POST /cluster/jobs/realm-sync/{id}","method":"POST","path":"/cluster/jobs/realm-sync/{id}","section":"cluster","summary":"create_job","description":"Create new realm-sync job.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the job.","format":"pve-configid"}],"requestParameters":[{"name":"schedule","type":"string","required":true,"description":"Backup schedule. The format is a subset of `systemd` calendar events.","format":"pve-calendar-event"},{"name":"comment","type":"string","required":false,"description":"Description for the Job."},{"name":"enable-new","type":"boolean","required":false,"description":"Enable newly synced users immediately.","default":"1"},{"name":"enabled","type":"boolean","required":false,"description":"Determines if the job is enabled.","default":1},{"name":"realm","type":"string","required":false,"description":"Authentication domain ID","format":"pve-realm"},{"name":"remove-vanished","type":"string","required":false,"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).","default":"none"},{"name":"scope","type":"string","required":false,"description":"Select what to sync.","enum":["users","groups","both"]}],"returns":{"type":"null"},"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/'."},"raw":{"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"}},"searchText":"POST\n/cluster/jobs/realm-sync/{id}\ncluster\ncreate_job\nCreate new realm-sync job.\nid string The ID of the job.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\ncomment string Description for the Job.\nenable-new boolean Enable newly synced users immediately.\nenabled boolean Determines if the job is enabled.\nrealm string Authentication domain ID\nremove-vanished string 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).\nscope string Select what to sync. users groups both"} +{"id":"PUT /cluster/jobs/realm-sync/{id}","method":"PUT","path":"/cluster/jobs/realm-sync/{id}","section":"cluster","summary":"update_job","description":"Update realm-sync job definition.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the job.","format":"pve-configid"}],"requestParameters":[{"name":"schedule","type":"string","required":true,"description":"Backup schedule. The format is a subset of `systemd` calendar events.","format":"pve-calendar-event"},{"name":"comment","type":"string","required":false,"description":"Description for the Job."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"enable-new","type":"boolean","required":false,"description":"Enable newly synced users immediately.","default":"1"},{"name":"enabled","type":"boolean","required":false,"description":"Determines if the job is enabled.","default":1},{"name":"remove-vanished","type":"string","required":false,"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).","default":"none"},{"name":"scope","type":"string","required":false,"description":"Select what to sync.","enum":["users","groups","both"]}],"returns":{"type":"null"},"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/'."},"raw":{"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"}},"searchText":"PUT\n/cluster/jobs/realm-sync/{id}\ncluster\nupdate_job\nUpdate realm-sync job definition.\nid string The ID of the job.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\ncomment string Description for the Job.\ndelete string A list of settings you want to delete.\nenable-new boolean Enable newly synced users immediately.\nenabled boolean Determines if the job is enabled.\nremove-vanished string 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).\nscope string Select what to sync. users groups both"} +{"id":"GET /cluster/jobs/schedule-analyze","method":"GET","path":"/cluster/jobs/schedule-analyze","section":"cluster","summary":"schedule-analyze","description":"Returns a list of future schedule runtimes.","pathParameters":[],"requestParameters":[{"name":"schedule","type":"string","required":true,"description":"Job schedule. The format is a subset of `systemd` calendar events.","format":"pve-calendar-event"},{"name":"iterations","type":"integer","required":false,"description":"Number of event-iteration to simulate and return.","default":10,"minimum":1,"maximum":100},{"name":"starttime","type":"integer","required":false,"description":"UNIX timestamp to start the calculation from. Defaults to the current time."}],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/jobs/schedule-analyze\ncluster\nschedule-analyze\nReturns a list of future schedule runtimes.\nschedule string Job schedule. The format is a subset of `systemd` calendar events.\niterations integer Number of event-iteration to simulate and return.\nstarttime integer UNIX timestamp to start the calculation from. Defaults to the current time."} +{"id":"GET /cluster/log","method":"GET","path":"/cluster/log","section":"cluster","summary":"log","description":"Read cluster log","pathParameters":[],"requestParameters":[{"name":"max","type":"integer","required":false,"description":"Maximum number of entries.","minimum":1}],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"permissions":{"description":"The user needs 'Sys.Syslog' on '/' in order to get all logs.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/log\ncluster\nlog\nRead cluster log\nmax integer Maximum number of entries."} +{"id":"GET /cluster/mapping","method":"GET","path":"/cluster/mapping","section":"cluster","summary":"index","description":"List resource types.","pathParameters":[],"requestParameters":[],"returns":{"items":{"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/mapping\ncluster\nindex\nList resource types."} +{"id":"GET /cluster/mapping/dir","method":"GET","path":"/cluster/mapping/dir","section":"cluster","summary":"index","description":"List directory mapping","pathParameters":[],"requestParameters":[{"name":"check-node","type":"string","required":false,"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"}],"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"},"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/mapping/dir\ncluster\nindex\nList directory mapping\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response."} +{"id":"POST /cluster/mapping/dir","method":"POST","path":"/cluster/mapping/dir","section":"cluster","summary":"create","description":"Create a new directory mapping.","pathParameters":[],"requestParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the directory mapping","format":"pve-configid"},{"name":"map","type":"array","required":true,"description":"A list of maps for the cluster nodes."},{"name":"description","type":"string","required":false,"description":"Description of the directory mapping"}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/dir",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/mapping/dir\ncluster\ncreate\nCreate a new directory mapping.\nid string The ID of the directory mapping\nmap array A list of maps for the cluster nodes.\ndescription string Description of the directory mapping"} +{"id":"DELETE /cluster/mapping/dir/{id}","method":"DELETE","path":"/cluster/mapping/dir/{id}","section":"cluster","summary":"delete","description":"Remove directory mapping.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/dir",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/mapping/dir/{id}\ncluster\ndelete\nRemove directory mapping.\nid string"} +{"id":"GET /cluster/mapping/dir/{id}","method":"GET","path":"/cluster/mapping/dir/{id}","section":"cluster","summary":"get","description":"Get directory mapping.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["or",["perm","/mapping/dir/{id}",["Mapping.Use"]],["perm","/mapping/dir/{id}",["Mapping.Modify"]],["perm","/mapping/dir/{id}",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/mapping/dir/{id}\ncluster\nget\nGet directory mapping.\nid string"} +{"id":"PUT /cluster/mapping/dir/{id}","method":"PUT","path":"/cluster/mapping/dir/{id}","section":"cluster","summary":"update","description":"Update a directory mapping.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the directory mapping","format":"pve-configid"}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Description of the directory mapping"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"map","type":"array","required":false,"description":"A list of maps for the cluster nodes."}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/dir/{id}",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/mapping/dir/{id}\ncluster\nupdate\nUpdate a directory mapping.\nid string The ID of the directory mapping\ndelete string A list of settings you want to delete.\ndescription string Description of the directory mapping\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nmap array A list of maps for the cluster nodes."} +{"id":"GET /cluster/mapping/pci","method":"GET","path":"/cluster/mapping/pci","section":"cluster","summary":"index","description":"List PCI Hardware Mapping","pathParameters":[],"requestParameters":[{"name":"check-node","type":"string","required":false,"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"}],"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"},"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/mapping/pci\ncluster\nindex\nList PCI Hardware Mapping\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response."} +{"id":"POST /cluster/mapping/pci","method":"POST","path":"/cluster/mapping/pci","section":"cluster","summary":"create","description":"Create a new hardware mapping.","pathParameters":[],"requestParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the logical PCI mapping.","format":"pve-configid"},{"name":"map","type":"array","required":true,"description":"A list of maps for the cluster nodes."},{"name":"description","type":"string","required":false,"description":"Description of the logical PCI device."},{"name":"live-migration-capable","type":"boolean","required":false,"description":"Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.","default":0},{"name":"mdev","type":"boolean","required":false,"description":"Marks the device(s) as being capable of providing mediated devices.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/pci",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/mapping/pci\ncluster\ncreate\nCreate a new hardware mapping.\nid string The ID of the logical PCI mapping.\nmap array A list of maps for the cluster nodes.\ndescription string Description of the logical PCI device.\nlive-migration-capable boolean Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.\nmdev boolean Marks the device(s) as being capable of providing mediated devices."} +{"id":"DELETE /cluster/mapping/pci/{id}","method":"DELETE","path":"/cluster/mapping/pci/{id}","section":"cluster","summary":"delete","description":"Remove Hardware Mapping.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/pci",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/mapping/pci/{id}\ncluster\ndelete\nRemove Hardware Mapping.\nid string"} +{"id":"GET /cluster/mapping/pci/{id}","method":"GET","path":"/cluster/mapping/pci/{id}","section":"cluster","summary":"get","description":"Get PCI Mapping.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["or",["perm","/mapping/pci/{id}",["Mapping.Use"]],["perm","/mapping/pci/{id}",["Mapping.Modify"]],["perm","/mapping/pci/{id}",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/mapping/pci/{id}\ncluster\nget\nGet PCI Mapping.\nid string"} +{"id":"PUT /cluster/mapping/pci/{id}","method":"PUT","path":"/cluster/mapping/pci/{id}","section":"cluster","summary":"update","description":"Update a hardware mapping.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the logical PCI mapping.","format":"pve-configid"}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Description of the logical PCI device."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"live-migration-capable","type":"boolean","required":false,"description":"Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.","default":0},{"name":"map","type":"array","required":false,"description":"A list of maps for the cluster nodes."},{"name":"mdev","type":"boolean","required":false,"description":"Marks the device(s) as being capable of providing mediated devices.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/pci/{id}",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/mapping/pci/{id}\ncluster\nupdate\nUpdate a hardware mapping.\nid string The ID of the logical PCI mapping.\ndelete string A list of settings you want to delete.\ndescription string Description of the logical PCI device.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nlive-migration-capable boolean Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.\nmap array A list of maps for the cluster nodes.\nmdev boolean Marks the device(s) as being capable of providing mediated devices."} +{"id":"GET /cluster/mapping/usb","method":"GET","path":"/cluster/mapping/usb","section":"cluster","summary":"index","description":"List USB Hardware Mappings","pathParameters":[],"requestParameters":[{"name":"check-node","type":"string","required":false,"description":"If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices.","format":"pve-node"}],"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"},"permissions":{"description":"Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/mapping/usb\ncluster\nindex\nList USB Hardware Mappings\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices."} +{"id":"POST /cluster/mapping/usb","method":"POST","path":"/cluster/mapping/usb","section":"cluster","summary":"create","description":"Create a new hardware mapping.","pathParameters":[],"requestParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the logical USB mapping.","format":"pve-configid"},{"name":"map","type":"array","required":true,"description":"A list of maps for the cluster nodes."},{"name":"description","type":"string","required":false,"description":"Description of the logical USB device."}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/usb",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/mapping/usb\ncluster\ncreate\nCreate a new hardware mapping.\nid string The ID of the logical USB mapping.\nmap array A list of maps for the cluster nodes.\ndescription string Description of the logical USB device."} +{"id":"DELETE /cluster/mapping/usb/{id}","method":"DELETE","path":"/cluster/mapping/usb/{id}","section":"cluster","summary":"delete","description":"Remove Hardware Mapping.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/usb",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/mapping/usb/{id}\ncluster\ndelete\nRemove Hardware Mapping.\nid string"} +{"id":"GET /cluster/mapping/usb/{id}","method":"GET","path":"/cluster/mapping/usb/{id}","section":"cluster","summary":"get","description":"Get USB Mapping.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["or",["perm","/mapping/usb/{id}",["Mapping.Audit"]],["perm","/mapping/usb/{id}",["Mapping.Use"]],["perm","/mapping/usb/{id}",["Mapping.Modify"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/mapping/usb/{id}\ncluster\nget\nGet USB Mapping.\nid string"} +{"id":"PUT /cluster/mapping/usb/{id}","method":"PUT","path":"/cluster/mapping/usb/{id}","section":"cluster","summary":"update","description":"Update a hardware mapping.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the logical USB mapping.","format":"pve-configid"}],"requestParameters":[{"name":"map","type":"array","required":true,"description":"A list of maps for the cluster nodes."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Description of the logical USB device."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/usb/{id}",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/mapping/usb/{id}\ncluster\nupdate\nUpdate a hardware mapping.\nid string The ID of the logical USB mapping.\nmap array A list of maps for the cluster nodes.\ndelete string A list of settings you want to delete.\ndescription string Description of the logical USB device.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /cluster/metrics","method":"GET","path":"/cluster/metrics","section":"cluster","summary":"index","description":"Metrics index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/metrics\ncluster\nindex\nMetrics index."} +{"id":"GET /cluster/metrics/export","method":"GET","path":"/cluster/metrics/export","section":"cluster","summary":"export","description":"Retrieve metrics of the cluster.","pathParameters":[],"requestParameters":[{"name":"history","type":"boolean","required":false,"description":"Also return historic values. Returns full available metric history unless `start-time` is also set","default":0},{"name":"local-only","type":"boolean","required":false,"description":"Only return metrics for the current node instead of the whole cluster","default":0},{"name":"node-list","type":"string","required":false,"description":"Only return metrics from nodes passed as comma-separated list"},{"name":"start-time","type":"integer","required":false,"description":"Only include metrics with a timestamp > start-time.","default":0}],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/metrics/export\ncluster\nexport\nRetrieve metrics of the cluster.\nhistory boolean Also return historic values. Returns full available metric history unless `start-time` is also set\nlocal-only boolean Only return metrics for the current node instead of the whole cluster\nnode-list string Only return metrics from nodes passed as comma-separated list\nstart-time integer Only include metrics with a timestamp > start-time."} +{"id":"GET /cluster/metrics/server","method":"GET","path":"/cluster/metrics/server","section":"cluster","summary":"server_index","description":"List configured metric servers.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/metrics/server\ncluster\nserver_index\nList configured metric servers."} +{"id":"DELETE /cluster/metrics/server/{id}","method":"DELETE","path":"/cluster/metrics/server/{id}","section":"cluster","summary":"delete","description":"Remove Metric server.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/metrics/server/{id}\ncluster\ndelete\nRemove Metric server.\nid string"} +{"id":"GET /cluster/metrics/server/{id}","method":"GET","path":"/cluster/metrics/server/{id}","section":"cluster","summary":"read","description":"Read metric server configuration.","pathParameters":[{"name":"id","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/metrics/server/{id}\ncluster\nread\nRead metric server configuration.\nid string"} +{"id":"POST /cluster/metrics/server/{id}","method":"POST","path":"/cluster/metrics/server/{id}","section":"cluster","summary":"create","description":"Create a new external metric server config","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the entry.","format":"pve-configid"}],"requestParameters":[{"name":"port","type":"integer","required":true,"description":"server network port","minimum":1,"maximum":65536},{"name":"server","type":"string","required":true,"description":"server dns name or IP address","format":"address"},{"name":"type","type":"string","required":true,"description":"Plugin type.","enum":["graphite","influxdb","opentelemetry"],"format":"pve-configid"},{"name":"api-path-prefix","type":"string","required":false,"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy."},{"name":"bucket","type":"string","required":false,"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api."},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable the plugin."},{"name":"influxdbproto","type":"string","required":false,"enum":["udp","http","https"],"default":"udp"},{"name":"max-body-size","type":"integer","required":false,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","default":25000000,"minimum":1},{"name":"mtu","type":"integer","required":false,"description":"MTU for metrics transmission over UDP","default":1500,"minimum":512,"maximum":65536},{"name":"organization","type":"string","required":false,"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api."},{"name":"otel-compression","type":"string","required":false,"description":"Compression algorithm for requests","enum":["none","gzip"],"default":"gzip"},{"name":"otel-headers","type":"string","required":false,"description":"Custom HTTP headers (JSON format, base64 encoded)"},{"name":"otel-max-body-size","type":"integer","required":false,"description":"Maximum request body size in bytes","default":10000000,"minimum":1024},{"name":"otel-path","type":"string","required":false,"description":"OTLP endpoint path","default":"/v1/metrics"},{"name":"otel-protocol","type":"string","required":false,"description":"HTTP protocol","enum":["http","https"],"default":"https"},{"name":"otel-resource-attributes","type":"string","required":false,"description":"Additional resource attributes as JSON, base64 encoded"},{"name":"otel-timeout","type":"integer","required":false,"description":"HTTP request timeout in seconds","default":5,"minimum":1,"maximum":10},{"name":"otel-verify-ssl","type":"boolean","required":false,"description":"Verify SSL certificates","default":1},{"name":"path","type":"string","required":false,"description":"root graphite path (ex: proxmox.mycluster.mykey)","format":"graphite-path"},{"name":"proto","type":"string","required":false,"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"]},{"name":"timeout","type":"integer","required":false,"description":"graphite TCP socket timeout (default=1)","default":1,"minimum":0},{"name":"token","type":"string","required":false,"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead."},{"name":"verify-certificate","type":"boolean","required":false,"description":"Set to 0 to disable certificate verification for https endpoints.","default":1}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/metrics/server/{id}\ncluster\ncreate\nCreate a new external metric server config\nid string The ID of the entry.\nport integer server network port\nserver string server dns name or IP address\ntype string Plugin type. graphite influxdb opentelemetry\napi-path-prefix string An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.\nbucket string The InfluxDB bucket/db. Only necessary when using the http v2 api.\ndisable boolean Flag to disable the plugin.\ninfluxdbproto string udp http https\nmax-body-size integer InfluxDB max-body-size in bytes. Requests are batched up to this size.\nmtu integer MTU for metrics transmission over UDP\norganization string The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.\notel-compression string Compression algorithm for requests none gzip\notel-headers string Custom HTTP headers (JSON format, base64 encoded)\notel-max-body-size integer Maximum request body size in bytes\notel-path string OTLP endpoint path\notel-protocol string HTTP protocol http https\notel-resource-attributes string Additional resource attributes as JSON, base64 encoded\notel-timeout integer HTTP request timeout in seconds\notel-verify-ssl boolean Verify SSL certificates\npath string root graphite path (ex: proxmox.mycluster.mykey)\nproto string Protocol to send graphite data. TCP or UDP (default) udp tcp\ntimeout integer graphite TCP socket timeout (default=1)\ntoken string The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.\nverify-certificate boolean Set to 0 to disable certificate verification for https endpoints."} +{"id":"PUT /cluster/metrics/server/{id}","method":"PUT","path":"/cluster/metrics/server/{id}","section":"cluster","summary":"update","description":"Update metric server configuration.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the entry.","format":"pve-configid"}],"requestParameters":[{"name":"port","type":"integer","required":true,"description":"server network port","minimum":1,"maximum":65536},{"name":"server","type":"string","required":true,"description":"server dns name or IP address","format":"address"},{"name":"api-path-prefix","type":"string","required":false,"description":"An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy."},{"name":"bucket","type":"string","required":false,"description":"The InfluxDB bucket/db. Only necessary when using the http v2 api."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable the plugin."},{"name":"influxdbproto","type":"string","required":false,"enum":["udp","http","https"],"default":"udp"},{"name":"max-body-size","type":"integer","required":false,"description":"InfluxDB max-body-size in bytes. Requests are batched up to this size.","default":25000000,"minimum":1},{"name":"mtu","type":"integer","required":false,"description":"MTU for metrics transmission over UDP","default":1500,"minimum":512,"maximum":65536},{"name":"organization","type":"string","required":false,"description":"The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api."},{"name":"otel-compression","type":"string","required":false,"description":"Compression algorithm for requests","enum":["none","gzip"],"default":"gzip"},{"name":"otel-headers","type":"string","required":false,"description":"Custom HTTP headers (JSON format, base64 encoded)"},{"name":"otel-max-body-size","type":"integer","required":false,"description":"Maximum request body size in bytes","default":10000000,"minimum":1024},{"name":"otel-path","type":"string","required":false,"description":"OTLP endpoint path","default":"/v1/metrics"},{"name":"otel-protocol","type":"string","required":false,"description":"HTTP protocol","enum":["http","https"],"default":"https"},{"name":"otel-resource-attributes","type":"string","required":false,"description":"Additional resource attributes as JSON, base64 encoded"},{"name":"otel-timeout","type":"integer","required":false,"description":"HTTP request timeout in seconds","default":5,"minimum":1,"maximum":10},{"name":"otel-verify-ssl","type":"boolean","required":false,"description":"Verify SSL certificates","default":1},{"name":"path","type":"string","required":false,"description":"root graphite path (ex: proxmox.mycluster.mykey)","format":"graphite-path"},{"name":"proto","type":"string","required":false,"description":"Protocol to send graphite data. TCP or UDP (default)","enum":["udp","tcp"]},{"name":"timeout","type":"integer","required":false,"description":"graphite TCP socket timeout (default=1)","default":1,"minimum":0},{"name":"token","type":"string","required":false,"description":"The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead."},{"name":"verify-certificate","type":"boolean","required":false,"description":"Set to 0 to disable certificate verification for https endpoints.","default":1}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/metrics/server/{id}\ncluster\nupdate\nUpdate metric server configuration.\nid string The ID of the entry.\nport integer server network port\nserver string server dns name or IP address\napi-path-prefix string An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.\nbucket string The InfluxDB bucket/db. Only necessary when using the http v2 api.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the plugin.\ninfluxdbproto string udp http https\nmax-body-size integer InfluxDB max-body-size in bytes. Requests are batched up to this size.\nmtu integer MTU for metrics transmission over UDP\norganization string The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.\notel-compression string Compression algorithm for requests none gzip\notel-headers string Custom HTTP headers (JSON format, base64 encoded)\notel-max-body-size integer Maximum request body size in bytes\notel-path string OTLP endpoint path\notel-protocol string HTTP protocol http https\notel-resource-attributes string Additional resource attributes as JSON, base64 encoded\notel-timeout integer HTTP request timeout in seconds\notel-verify-ssl boolean Verify SSL certificates\npath string root graphite path (ex: proxmox.mycluster.mykey)\nproto string Protocol to send graphite data. TCP or UDP (default) udp tcp\ntimeout integer graphite TCP socket timeout (default=1)\ntoken string The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.\nverify-certificate boolean Set to 0 to disable certificate verification for https endpoints."} +{"id":"GET /cluster/nextid","method":"GET","path":"/cluster/nextid","section":"cluster","summary":"nextid","description":"Get next free VMID. Pass a VMID to assert that its free (at time of check).","pathParameters":[],"requestParameters":[{"name":"vmid","type":"integer","required":false,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"returns":{"description":"The next free VMID.","type":"integer"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/nextid\ncluster\nnextid\nGet next free VMID. Pass a VMID to assert that its free (at time of check).\nvmid integer The (unique) ID of the VM."} +{"id":"GET /cluster/notifications","method":"GET","path":"/cluster/notifications","section":"cluster","summary":"index","description":"Index for notification-related API endpoints.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/notifications\ncluster\nindex\nIndex for notification-related API endpoints."} +{"id":"GET /cluster/notifications/endpoints","method":"GET","path":"/cluster/notifications/endpoints","section":"cluster","summary":"endpoints_index","description":"Index for all available endpoint types.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints\ncluster\nendpoints_index\nIndex for all available endpoint types."} +{"id":"GET /cluster/notifications/endpoints/gotify","method":"GET","path":"/cluster/notifications/endpoints/gotify","section":"cluster","summary":"get_gotify_endpoints","description":"Returns a list of all gotify endpoints","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/gotify\ncluster\nget_gotify_endpoints\nReturns a list of all gotify endpoints"} +{"id":"POST /cluster/notifications/endpoints/gotify","method":"POST","path":"/cluster/notifications/endpoints/gotify","section":"cluster","summary":"create_gotify_endpoint","description":"Create a new gotify endpoint","pathParameters":[],"requestParameters":[{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"},{"name":"server","type":"string","required":true,"description":"Server URL"},{"name":"token","type":"string","required":true,"description":"Secret token"},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"POST\n/cluster/notifications/endpoints/gotify\ncluster\ncreate_gotify_endpoint\nCreate a new gotify endpoint\nname string The name of the endpoint.\nserver string Server URL\ntoken string Secret token\ncomment string Comment\ndisable boolean Disable this target"} +{"id":"DELETE /cluster/notifications/endpoints/gotify/{name}","method":"DELETE","path":"/cluster/notifications/endpoints/gotify/{name}","section":"cluster","summary":"delete_gotify_endpoint","description":"Remove gotify endpoint","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/notifications/endpoints/gotify/{name}\ncluster\ndelete_gotify_endpoint\nRemove gotify endpoint\nname string"} +{"id":"GET /cluster/notifications/endpoints/gotify/{name}","method":"GET","path":"/cluster/notifications/endpoints/gotify/{name}","section":"cluster","summary":"get_gotify_endpoint","description":"Return a specific gotify endpoint","pathParameters":[{"name":"name","type":"string","required":true,"description":"Name of the endpoint.","format":"pve-configid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/gotify/{name}\ncluster\nget_gotify_endpoint\nReturn a specific gotify endpoint\nname string Name of the endpoint."} +{"id":"PUT /cluster/notifications/endpoints/gotify/{name}","method":"PUT","path":"/cluster/notifications/endpoints/gotify/{name}","section":"cluster","summary":"update_gotify_endpoint","description":"Update existing gotify endpoint","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"}],"requestParameters":[{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"delete","type":"array","required":false,"description":"A list of settings you want to delete."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0},{"name":"server","type":"string","required":false,"description":"Server URL"},{"name":"token","type":"string","required":false,"description":"Secret token"}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"PUT\n/cluster/notifications/endpoints/gotify/{name}\ncluster\nupdate_gotify_endpoint\nUpdate existing gotify endpoint\nname string The name of the endpoint.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nserver string Server URL\ntoken string Secret token"} +{"id":"GET /cluster/notifications/endpoints/sendmail","method":"GET","path":"/cluster/notifications/endpoints/sendmail","section":"cluster","summary":"get_sendmail_endpoints","description":"Returns a list of all sendmail endpoints","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/sendmail\ncluster\nget_sendmail_endpoints\nReturns a list of all sendmail endpoints"} +{"id":"POST /cluster/notifications/endpoints/sendmail","method":"POST","path":"/cluster/notifications/endpoints/sendmail","section":"cluster","summary":"create_sendmail_endpoint","description":"Create a new sendmail endpoint","pathParameters":[],"requestParameters":[{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"},{"name":"author","type":"string","required":false,"description":"Author of the mail"},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0},{"name":"from-address","type":"string","required":false,"description":"`From` address for the mail"},{"name":"mailto","type":"array","required":false,"description":"List of email recipients"},{"name":"mailto-user","type":"array","required":false,"description":"List of users"}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"POST\n/cluster/notifications/endpoints/sendmail\ncluster\ncreate_sendmail_endpoint\nCreate a new sendmail endpoint\nname string The name of the endpoint.\nauthor string Author of the mail\ncomment string Comment\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users"} +{"id":"DELETE /cluster/notifications/endpoints/sendmail/{name}","method":"DELETE","path":"/cluster/notifications/endpoints/sendmail/{name}","section":"cluster","summary":"delete_sendmail_endpoint","description":"Remove sendmail endpoint","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\ndelete_sendmail_endpoint\nRemove sendmail endpoint\nname string"} +{"id":"GET /cluster/notifications/endpoints/sendmail/{name}","method":"GET","path":"/cluster/notifications/endpoints/sendmail/{name}","section":"cluster","summary":"get_sendmail_endpoint","description":"Return a specific sendmail endpoint","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\nget_sendmail_endpoint\nReturn a specific sendmail endpoint\nname string"} +{"id":"PUT /cluster/notifications/endpoints/sendmail/{name}","method":"PUT","path":"/cluster/notifications/endpoints/sendmail/{name}","section":"cluster","summary":"update_sendmail_endpoint","description":"Update existing sendmail endpoint","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"}],"requestParameters":[{"name":"author","type":"string","required":false,"description":"Author of the mail"},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"delete","type":"array","required":false,"description":"A list of settings you want to delete."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0},{"name":"from-address","type":"string","required":false,"description":"`From` address for the mail"},{"name":"mailto","type":"array","required":false,"description":"List of email recipients"},{"name":"mailto-user","type":"array","required":false,"description":"List of users"}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"PUT\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\nupdate_sendmail_endpoint\nUpdate existing sendmail endpoint\nname string The name of the endpoint.\nauthor string Author of the mail\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users"} +{"id":"GET /cluster/notifications/endpoints/smtp","method":"GET","path":"/cluster/notifications/endpoints/smtp","section":"cluster","summary":"get_smtp_endpoints","description":"Returns a list of all smtp endpoints","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/smtp\ncluster\nget_smtp_endpoints\nReturns a list of all smtp endpoints"} +{"id":"POST /cluster/notifications/endpoints/smtp","method":"POST","path":"/cluster/notifications/endpoints/smtp","section":"cluster","summary":"create_smtp_endpoint","description":"Create a new smtp endpoint","pathParameters":[],"requestParameters":[{"name":"from-address","type":"string","required":true,"description":"`From` address for the mail"},{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"},{"name":"server","type":"string","required":true,"description":"The address of the SMTP server."},{"name":"author","type":"string","required":false,"description":"Author of the mail. Defaults to 'Proxmox VE'."},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0},{"name":"mailto","type":"array","required":false,"description":"List of email recipients"},{"name":"mailto-user","type":"array","required":false,"description":"List of users"},{"name":"mode","type":"string","required":false,"description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"default":"tls"},{"name":"password","type":"string","required":false,"description":"Password for SMTP authentication"},{"name":"port","type":"integer","required":false,"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."},{"name":"username","type":"string","required":false,"description":"Username for SMTP authentication"}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"POST\n/cluster/notifications/endpoints/smtp\ncluster\ncreate_smtp_endpoint\nCreate a new smtp endpoint\nfrom-address string `From` address for the mail\nname string The name of the endpoint.\nserver string The address of the SMTP server.\nauthor string Author of the mail. Defaults to 'Proxmox VE'.\ncomment string Comment\ndisable boolean Disable this target\nmailto array List of email recipients\nmailto-user array List of users\nmode string Determine which encryption method shall be used for the connection. insecure starttls tls\npassword string Password for SMTP authentication\nport integer 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.\nusername string Username for SMTP authentication"} +{"id":"DELETE /cluster/notifications/endpoints/smtp/{name}","method":"DELETE","path":"/cluster/notifications/endpoints/smtp/{name}","section":"cluster","summary":"delete_smtp_endpoint","description":"Remove smtp endpoint","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/notifications/endpoints/smtp/{name}\ncluster\ndelete_smtp_endpoint\nRemove smtp endpoint\nname string"} +{"id":"GET /cluster/notifications/endpoints/smtp/{name}","method":"GET","path":"/cluster/notifications/endpoints/smtp/{name}","section":"cluster","summary":"get_smtp_endpoint","description":"Return a specific smtp endpoint","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/smtp/{name}\ncluster\nget_smtp_endpoint\nReturn a specific smtp endpoint\nname string"} +{"id":"PUT /cluster/notifications/endpoints/smtp/{name}","method":"PUT","path":"/cluster/notifications/endpoints/smtp/{name}","section":"cluster","summary":"update_smtp_endpoint","description":"Update existing smtp endpoint","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"}],"requestParameters":[{"name":"author","type":"string","required":false,"description":"Author of the mail. Defaults to 'Proxmox VE'."},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"delete","type":"array","required":false,"description":"A list of settings you want to delete."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0},{"name":"from-address","type":"string","required":false,"description":"`From` address for the mail"},{"name":"mailto","type":"array","required":false,"description":"List of email recipients"},{"name":"mailto-user","type":"array","required":false,"description":"List of users"},{"name":"mode","type":"string","required":false,"description":"Determine which encryption method shall be used for the connection.","enum":["insecure","starttls","tls"],"default":"tls"},{"name":"password","type":"string","required":false,"description":"Password for SMTP authentication"},{"name":"port","type":"integer","required":false,"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."},{"name":"server","type":"string","required":false,"description":"The address of the SMTP server."},{"name":"username","type":"string","required":false,"description":"Username for SMTP authentication"}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"PUT\n/cluster/notifications/endpoints/smtp/{name}\ncluster\nupdate_smtp_endpoint\nUpdate existing smtp endpoint\nname string The name of the endpoint.\nauthor string Author of the mail. Defaults to 'Proxmox VE'.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users\nmode string Determine which encryption method shall be used for the connection. insecure starttls tls\npassword string Password for SMTP authentication\nport integer 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.\nserver string The address of the SMTP server.\nusername string Username for SMTP authentication"} +{"id":"GET /cluster/notifications/endpoints/webhook","method":"GET","path":"/cluster/notifications/endpoints/webhook","section":"cluster","summary":"get_webhook_endpoints","description":"Returns a list of all webhook endpoints","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/webhook\ncluster\nget_webhook_endpoints\nReturns a list of all webhook endpoints"} +{"id":"POST /cluster/notifications/endpoints/webhook","method":"POST","path":"/cluster/notifications/endpoints/webhook","section":"cluster","summary":"create_webhook_endpoint","description":"Create a new webhook endpoint","pathParameters":[],"requestParameters":[{"name":"method","type":"string","required":true,"description":"HTTP method","enum":["post","put","get"]},{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"},{"name":"url","type":"string","required":true,"description":"Server URL"},{"name":"body","type":"string","required":false,"description":"HTTP body, base64 encoded"},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0},{"name":"header","type":"array","required":false,"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value="},{"name":"secret","type":"array","required":false,"description":"Secrets to set. These have to be formatted as a property string in the format name=,value="}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"POST\n/cluster/notifications/endpoints/webhook\ncluster\ncreate_webhook_endpoint\nCreate a new webhook endpoint\nmethod string HTTP method post put get\nname string The name of the endpoint.\nurl string Server URL\nbody string HTTP body, base64 encoded\ncomment string Comment\ndisable boolean Disable this target\nheader array HTTP headers to set. These have to be formatted as a property string in the format name=,value=\nsecret array Secrets to set. These have to be formatted as a property string in the format name=,value="} +{"id":"DELETE /cluster/notifications/endpoints/webhook/{name}","method":"DELETE","path":"/cluster/notifications/endpoints/webhook/{name}","section":"cluster","summary":"delete_webhook_endpoint","description":"Remove webhook endpoint","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/notifications/endpoints/webhook/{name}\ncluster\ndelete_webhook_endpoint\nRemove webhook endpoint\nname string"} +{"id":"GET /cluster/notifications/endpoints/webhook/{name}","method":"GET","path":"/cluster/notifications/endpoints/webhook/{name}","section":"cluster","summary":"get_webhook_endpoint","description":"Return a specific webhook endpoint","pathParameters":[{"name":"name","type":"string","required":true,"description":"Name of the endpoint.","format":"pve-configid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/endpoints/webhook/{name}\ncluster\nget_webhook_endpoint\nReturn a specific webhook endpoint\nname string Name of the endpoint."} +{"id":"PUT /cluster/notifications/endpoints/webhook/{name}","method":"PUT","path":"/cluster/notifications/endpoints/webhook/{name}","section":"cluster","summary":"update_webhook_endpoint","description":"Update existing webhook endpoint","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the endpoint.","format":"pve-configid"}],"requestParameters":[{"name":"body","type":"string","required":false,"description":"HTTP body, base64 encoded"},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"delete","type":"array","required":false,"description":"A list of settings you want to delete."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Disable this target","default":0},{"name":"header","type":"array","required":false,"description":"HTTP headers to set. These have to be formatted as a property string in the format name=,value="},{"name":"method","type":"string","required":false,"description":"HTTP method","enum":["post","put","get"]},{"name":"secret","type":"array","required":false,"description":"Secrets to set. These have to be formatted as a property string in the format name=,value="},{"name":"url","type":"string","required":false,"description":"Server URL"}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/mapping/notifications",["Mapping.Modify"]],["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/",["Sys.AccessNetwork"]]]]},"raw":{"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"}},"searchText":"PUT\n/cluster/notifications/endpoints/webhook/{name}\ncluster\nupdate_webhook_endpoint\nUpdate existing webhook endpoint\nname string The name of the endpoint.\nbody string HTTP body, base64 encoded\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nheader array HTTP headers to set. These have to be formatted as a property string in the format name=,value=\nmethod string HTTP method post put get\nsecret array Secrets to set. These have to be formatted as a property string in the format name=,value=\nurl string Server URL"} +{"id":"GET /cluster/notifications/matcher-field-values","method":"GET","path":"/cluster/notifications/matcher-field-values","section":"cluster","summary":"get_matcher_field_values","description":"Returns known notification metadata fields and their known values","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/matcher-field-values\ncluster\nget_matcher_field_values\nReturns known notification metadata fields and their known values"} +{"id":"GET /cluster/notifications/matcher-fields","method":"GET","path":"/cluster/notifications/matcher-fields","section":"cluster","summary":"get_matcher_fields","description":"Returns known notification metadata fields","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"name":{"description":"Name of the field.","type":"string"}},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/matcher-fields\ncluster\nget_matcher_fields\nReturns known notification metadata fields"} +{"id":"GET /cluster/notifications/matchers","method":"GET","path":"/cluster/notifications/matchers","section":"cluster","summary":"get_matchers","description":"Returns a list of all matchers","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/matchers\ncluster\nget_matchers\nReturns a list of all matchers"} +{"id":"POST /cluster/notifications/matchers","method":"POST","path":"/cluster/notifications/matchers","section":"cluster","summary":"create_matcher","description":"Create a new matcher","pathParameters":[],"requestParameters":[{"name":"name","type":"string","required":true,"description":"Name of the matcher.","format":"pve-configid"},{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"disable","type":"boolean","required":false,"description":"Disable this matcher","default":0},{"name":"invert-match","type":"boolean","required":false,"description":"Invert match of the whole matcher"},{"name":"match-calendar","type":"array","required":false,"description":"Match notification timestamp"},{"name":"match-field","type":"array","required":false,"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):="},{"name":"match-severity","type":"array","required":false,"description":"Notification severities to match"},{"name":"mode","type":"string","required":false,"description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"default":"all"},{"name":"target","type":"array","required":false,"description":"Targets to notify on match"}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/notifications/matchers\ncluster\ncreate_matcher\nCreate a new matcher\nname string Name of the matcher.\ncomment string Comment\ndisable boolean Disable this matcher\ninvert-match boolean Invert match of the whole matcher\nmatch-calendar array Match notification timestamp\nmatch-field array Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=\nmatch-severity array Notification severities to match\nmode string Choose between 'all' and 'any' for when multiple properties are specified all any\ntarget array Targets to notify on match"} +{"id":"DELETE /cluster/notifications/matchers/{name}","method":"DELETE","path":"/cluster/notifications/matchers/{name}","section":"cluster","summary":"delete_matcher","description":"Remove matcher","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/notifications/matchers/{name}\ncluster\ndelete_matcher\nRemove matcher\nname string"} +{"id":"GET /cluster/notifications/matchers/{name}","method":"GET","path":"/cluster/notifications/matchers/{name}","section":"cluster","summary":"get_matcher","description":"Return a specific matcher","pathParameters":[{"name":"name","type":"string","required":true,"format":"pve-configid"}],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/matchers/{name}\ncluster\nget_matcher\nReturn a specific matcher\nname string"} +{"id":"PUT /cluster/notifications/matchers/{name}","method":"PUT","path":"/cluster/notifications/matchers/{name}","section":"cluster","summary":"update_matcher","description":"Update existing matcher","pathParameters":[{"name":"name","type":"string","required":true,"description":"Name of the matcher.","format":"pve-configid"}],"requestParameters":[{"name":"comment","type":"string","required":false,"description":"Comment"},{"name":"delete","type":"array","required":false,"description":"A list of settings you want to delete."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Disable this matcher","default":0},{"name":"invert-match","type":"boolean","required":false,"description":"Invert match of the whole matcher"},{"name":"match-calendar","type":"array","required":false,"description":"Match notification timestamp"},{"name":"match-field","type":"array","required":false,"description":"Metadata fields to match (regex or exact match). Must be in the form (regex|exact):="},{"name":"match-severity","type":"array","required":false,"description":"Notification severities to match"},{"name":"mode","type":"string","required":false,"description":"Choose between 'all' and 'any' for when multiple properties are specified","enum":["all","any"],"default":"all"},{"name":"target","type":"array","required":false,"description":"Targets to notify on match"}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/notifications",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/notifications/matchers/{name}\ncluster\nupdate_matcher\nUpdate existing matcher\nname string Name of the matcher.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this matcher\ninvert-match boolean Invert match of the whole matcher\nmatch-calendar array Match notification timestamp\nmatch-field array Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=\nmatch-severity array Notification severities to match\nmode string Choose between 'all' and 'any' for when multiple properties are specified all any\ntarget array Targets to notify on match"} +{"id":"GET /cluster/notifications/targets","method":"GET","path":"/cluster/notifications/targets","section":"cluster","summary":"get_all_targets","description":"Returns a list of all entities that can be used as notification targets.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/notifications/targets\ncluster\nget_all_targets\nReturns a list of all entities that can be used as notification targets."} +{"id":"POST /cluster/notifications/targets/{name}/test","method":"POST","path":"/cluster/notifications/targets/{name}/test","section":"cluster","summary":"test_target","description":"Send a test notification to a provided target.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Name of the target.","format":"pve-configid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["or",["perm","/mapping/notifications",["Mapping.Modify"]],["perm","/mapping/notifications",["Mapping.Audit"]],["perm","/mapping/notifications",["Mapping.Use"]]]},"raw":{"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"}},"searchText":"POST\n/cluster/notifications/targets/{name}/test\ncluster\ntest_target\nSend a test notification to a provided target.\nname string Name of the target."} +{"id":"GET /cluster/options","method":"GET","path":"/cluster/options","section":"cluster","summary":"get_options","description":"Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned.","pathParameters":[],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]],"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/options\ncluster\nget_options\nGet datacenter options. Without 'Sys.Audit' on '/' not all options are returned."} +{"id":"PUT /cluster/options","method":"PUT","path":"/cluster/options","section":"cluster","summary":"set_options","description":"Set datacenter options.","pathParameters":[],"requestParameters":[{"name":"bwlimit","type":"string","required":false,"description":"Set I/O bandwidth limit for various operations (in KiB/s)."},{"name":"consent-text","type":"string","required":false,"description":"Consent text that is displayed before logging in."},{"name":"console","type":"string","required":false,"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"]},{"name":"crs","type":"string","required":false,"description":"Cluster resource scheduling settings."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file."},{"name":"email_from","type":"string","required":false,"description":"Specify email address to send notification from (default is root@$hostname)","format":"email-opt"},{"name":"fencing","type":"string","required":false,"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"],"default":"watchdog"},{"name":"ha","type":"string","required":false,"description":"Cluster wide HA settings."},{"name":"http_proxy","type":"string","required":false,"description":"Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')"},{"name":"keyboard","type":"string","required":false,"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"]},{"name":"language","type":"string","required":false,"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"]},{"name":"location","type":"string","required":false,"description":"The location of the cluster."},{"name":"mac_prefix","type":"string","required":false,"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).","default":"BC:24:11","format":"mac-prefix"},{"name":"max_workers","type":"integer","required":false,"description":"Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.","minimum":1},{"name":"migration","type":"string","required":false,"description":"For cluster wide migration settings."},{"name":"migration_unsecure","type":"boolean","required":false,"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!"},{"name":"next-id","type":"string","required":false,"description":"Control the range for the free VMID auto-selection pool."},{"name":"notify","type":"string","required":false,"description":"Cluster-wide notification settings."},{"name":"registered-tags","type":"string","required":false,"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`."},{"name":"replication","type":"string","required":false,"description":"For cluster wide replication settings."},{"name":"tag-style","type":"string","required":false,"description":"Tag style options."},{"name":"u2f","type":"string","required":false,"description":"u2f"},{"name":"user-tag-access","type":"string","required":false,"description":"Privilege options for user-settable tags"},{"name":"webauthn","type":"string","required":false,"description":"webauthn configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/options\ncluster\nset_options\nSet datacenter options.\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\nconsent-text string Consent text that is displayed before logging in.\nconsole string 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. applet vv html5 xtermjs\ncrs string Cluster resource scheduling settings.\ndelete string A list of settings you want to delete.\ndescription string Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.\nemail_from string Specify email address to send notification from (default is root@$hostname)\nfencing string 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 watchdog hardware both\nha string Cluster wide HA settings.\nhttp_proxy string Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')\nkeyboard string Default keybord layout for vnc server. 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\nlanguage string Default GUI language. 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\nlocation string The location of the cluster.\nmac_prefix string 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).\nmax_workers integer Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.\nmigration string For cluster wide migration settings.\nmigration_unsecure boolean 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!\nnext-id string Control the range for the free VMID auto-selection pool.\nnotify string Cluster-wide notification settings.\nregistered-tags string 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`.\nreplication string For cluster wide replication settings.\ntag-style string Tag style options.\nu2f string u2f\nuser-tag-access string Privilege options for user-settable tags\nwebauthn string webauthn configuration"} +{"id":"GET /cluster/qemu","method":"GET","path":"/cluster/qemu","section":"cluster","summary":"index","description":"Cluster-wide QEMU index","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/qemu\ncluster\nindex\nCluster-wide QEMU index\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /cluster/qemu/cpu-flags","method":"GET","path":"/cluster/qemu/cpu-flags","section":"cluster","summary":"index","description":"List of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64.","pathParameters":[],"requestParameters":[{"name":"accel","type":"string","required":false,"description":"Acceleration type to check node compatibility for.","enum":["kvm","tcg"],"default":"kvm"},{"name":"arch","type":"string","required":false,"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"]}],"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"},"permissions":{"check":["or",["perm","/nodes",["Sys.Audit"]],["perm","/mapping/cpu",["Mapping.Audit","Mapping.Use","Mapping.Modify"],"any",1]]},"raw":{"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"}},"searchText":"GET\n/cluster/qemu/cpu-flags\ncluster\nindex\nList of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64.\naccel string Acceleration type to check node compatibility for. kvm tcg\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /cluster/qemu/custom-cpu-models","method":"GET","path":"/cluster/qemu/custom-cpu-models","section":"cluster","summary":"config","description":"List all custom CPU model definitions visible to the user.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"description":"Only lists entries where the user has 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/cpu/'.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/qemu/custom-cpu-models\ncluster\nconfig\nList all custom CPU model definitions visible to the user.\nvm\nvirtual machine\nkvm guest"} +{"id":"POST /cluster/qemu/custom-cpu-models","method":"POST","path":"/cluster/qemu/custom-cpu-models","section":"cluster","summary":"create","description":"Add a custom CPU model definition.","pathParameters":[],"requestParameters":[{"name":"cputype","type":"string","required":true,"description":"Name for the custom CPU model. The 'custom-' prefix is optional.","format":"pve-configid"},{"name":"reported-model","type":"string","required":true,"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"],"default":"kvm64"},{"name":"flags","type":"string","required":false,"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"},{"name":"guest-phys-bits","type":"integer","required":false,"description":"Number of physical address bits available to the guest.","minimum":32,"maximum":64},{"name":"hidden","type":"boolean","required":false,"description":"Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.","default":0},{"name":"hv-vendor-id","type":"string","required":false,"description":"The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID."},{"name":"level","type":"integer","required":false,"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.","minimum":0,"maximum":4294967295},{"name":"phys-bits","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/cpu",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"POST\n/cluster/qemu/custom-cpu-models\ncluster\ncreate\nAdd a custom CPU model definition.\ncputype string Name for the custom CPU model. The 'custom-' prefix is optional.\nreported-model string 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. 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\nflags string 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\nguest-phys-bits integer Number of physical address bits available to the guest.\nhidden boolean Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.\nhv-vendor-id string The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.\nlevel integer 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.\nphys-bits string 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.\nvm\nvirtual machine\nkvm guest"} +{"id":"DELETE /cluster/qemu/custom-cpu-models/{cputype}","method":"DELETE","path":"/cluster/qemu/custom-cpu-models/{cputype}","section":"cluster","summary":"delete","description":"Delete a custom CPU model definition.","pathParameters":[{"name":"cputype","type":"string","required":true,"description":"The custom model to delete. The 'custom-' prefix is optional."}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/cpu/{cputype}",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\ndelete\nDelete a custom CPU model definition.\ncputype string The custom model to delete. The 'custom-' prefix is optional.\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /cluster/qemu/custom-cpu-models/{cputype}","method":"GET","path":"/cluster/qemu/custom-cpu-models/{cputype}","section":"cluster","summary":"info","description":"Retrieve details about a specific custom CPU model.","pathParameters":[{"name":"cputype","type":"string","required":true,"description":"Name of the CPU model to query. The 'custom-' prefix is optional."}],"requestParameters":[],"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"},"permissions":{"check":["or",["perm","/mapping/cpu/{cputype}",["Mapping.Audit"]],["perm","/mapping/cpu/{cputype}",["Mapping.Use"]],["perm","/mapping/cpu/{cputype}",["Mapping.Modify"]]]},"raw":{"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"}},"searchText":"GET\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\ninfo\nRetrieve details about a specific custom CPU model.\ncputype string Name of the CPU model to query. The 'custom-' prefix is optional.\nvm\nvirtual machine\nkvm guest"} +{"id":"PUT /cluster/qemu/custom-cpu-models/{cputype}","method":"PUT","path":"/cluster/qemu/custom-cpu-models/{cputype}","section":"cluster","summary":"update","description":"Update a custom CPU model definition.","pathParameters":[{"name":"cputype","type":"string","required":true,"description":"Name for the custom CPU model. The 'custom-' prefix is optional.","format":"pve-configid"}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of properties to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"flags","type":"string","required":false,"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"},{"name":"guest-phys-bits","type":"integer","required":false,"description":"Number of physical address bits available to the guest.","minimum":32,"maximum":64},{"name":"hidden","type":"boolean","required":false,"description":"Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.","default":0},{"name":"hv-vendor-id","type":"string","required":false,"description":"The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID."},{"name":"level","type":"integer","required":false,"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.","minimum":0,"maximum":4294967295},{"name":"phys-bits","type":"string","required":false,"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"},{"name":"reported-model","type":"string","required":false,"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"],"default":"kvm64"}],"returns":{"type":"null"},"permissions":{"check":["perm","/mapping/cpu/{cputype}",["Mapping.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\nupdate\nUpdate a custom CPU model definition.\ncputype string Name for the custom CPU model. The 'custom-' prefix is optional.\ndelete string A list of properties to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nflags string 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\nguest-phys-bits integer Number of physical address bits available to the guest.\nhidden boolean Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.\nhv-vendor-id string The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.\nlevel integer 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.\nphys-bits string 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.\nreported-model string 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. 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\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /cluster/replication","method":"GET","path":"/cluster/replication","section":"cluster","summary":"index","description":"List replication jobs.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"description":"Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/replication\ncluster\nindex\nList replication jobs."} +{"id":"POST /cluster/replication","method":"POST","path":"/cluster/replication","section":"cluster","summary":"create","description":"Create a new replication job","pathParameters":[],"requestParameters":[{"name":"id","type":"string","required":true,"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"},{"name":"target","type":"string","required":true,"description":"Target node.","format":"pve-node"},{"name":"type","type":"string","required":true,"description":"Section type.","enum":["local"]},{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable/deactivate the entry."},{"name":"rate","type":"number","required":false,"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":1},{"name":"remove_job","type":"string","required":false,"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"]},{"name":"schedule","type":"string","required":false,"description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","default":"*/15","format":"pve-calendar-event"},{"name":"source","type":"string","required":false,"description":"For internal use, to detect if the guest was stolen.","format":"pve-node"}],"returns":{"type":"null"},"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"POST\n/cluster/replication\ncluster\ncreate\nCreate a new replication job\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\ntarget string Target node.\ntype string Section type. local\ncomment string Description.\ndisable boolean Flag to disable/deactivate the entry.\nrate number Rate limit in mbps (megabytes per second) as floating point number.\nremove_job string 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. local full\nschedule string Storage replication schedule. The format is a subset of `systemd` calendar events.\nsource string For internal use, to detect if the guest was stolen."} +{"id":"DELETE /cluster/replication/{id}","method":"DELETE","path":"/cluster/replication/{id}","section":"cluster","summary":"delete","description":"Mark replication job for removal.","pathParameters":[{"name":"id","type":"string","required":true,"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"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Will remove the jobconfig entry, but will not cleanup.","default":0},{"name":"keep","type":"boolean","required":false,"description":"Keep replicated data at target (do not remove).","default":0}],"returns":{"type":"null"},"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"DELETE\n/cluster/replication/{id}\ncluster\ndelete\nMark replication job for removal.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nforce boolean Will remove the jobconfig entry, but will not cleanup.\nkeep boolean Keep replicated data at target (do not remove)."} +{"id":"GET /cluster/replication/{id}","method":"GET","path":"/cluster/replication/{id}","section":"cluster","summary":"read","description":"Read replication job configuration.","pathParameters":[{"name":"id","type":"string","required":true,"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"}],"requestParameters":[],"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"},"permissions":{"description":"Requires the VM.Audit permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/replication/{id}\ncluster\nread\nRead replication job configuration.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'."} +{"id":"PUT /cluster/replication/{id}","method":"PUT","path":"/cluster/replication/{id}","section":"cluster","summary":"update","description":"Update replication job configuration.","pathParameters":[{"name":"id","type":"string","required":true,"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"}],"requestParameters":[{"name":"comment","type":"string","required":false,"description":"Description."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable/deactivate the entry."},{"name":"rate","type":"number","required":false,"description":"Rate limit in mbps (megabytes per second) as floating point number.","minimum":1},{"name":"remove_job","type":"string","required":false,"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"]},{"name":"schedule","type":"string","required":false,"description":"Storage replication schedule. The format is a subset of `systemd` calendar events.","default":"*/15","format":"pve-calendar-event"},{"name":"source","type":"string","required":false,"description":"For internal use, to detect if the guest was stolen.","format":"pve-node"}],"returns":{"type":"null"},"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"PUT\n/cluster/replication/{id}\ncluster\nupdate\nUpdate replication job configuration.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable/deactivate the entry.\nrate number Rate limit in mbps (megabytes per second) as floating point number.\nremove_job string 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. local full\nschedule string Storage replication schedule. The format is a subset of `systemd` calendar events.\nsource string For internal use, to detect if the guest was stolen."} +{"id":"GET /cluster/resources","method":"GET","path":"/cluster/resources","section":"cluster","summary":"resources","description":"Resources index (cluster wide).","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Resource type.","enum":["vm","storage","node","sdn"]}],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/resources\ncluster\nresources\nResources index (cluster wide).\ntype string Resource type. vm storage node sdn"} +{"id":"GET /cluster/sdn","method":"GET","path":"/cluster/sdn","section":"cluster","summary":"index","description":"Directory index.","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"id":{"type":"string"}},"type":"object"},"links":[{"href":"{id}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/sdn",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn\ncluster\nindex\nDirectory index."} +{"id":"PUT /cluster/sdn","method":"PUT","path":"/cluster/sdn","section":"cluster","summary":"reload","description":"Apply sdn controller changes && reload.","pathParameters":[],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"release-lock","type":"boolean","required":false,"description":"When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards","default":1}],"returns":{"type":"string"},"permissions":{"check":["perm","/sdn",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn\ncluster\nreload\nApply sdn controller changes && reload.\nlock-token string the token for unlocking the global SDN configuration\nrelease-lock boolean When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards"} +{"id":"GET /cluster/sdn/controllers","method":"GET","path":"/cluster/sdn/controllers","section":"cluster","summary":"index","description":"SDN controllers index.","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."},{"name":"type","type":"string","required":false,"description":"Only list sdn controllers of specific type","enum":["bgp","evpn","faucet","isis"]}],"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"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/controllers\ncluster\nindex\nSDN controllers index.\npending boolean Display pending config.\nrunning boolean Display running config.\ntype string Only list sdn controllers of specific type bgp evpn faucet isis"} +{"id":"POST /cluster/sdn/controllers","method":"POST","path":"/cluster/sdn/controllers","section":"cluster","summary":"create","description":"Create a new sdn controller object.","pathParameters":[],"requestParameters":[{"name":"controller","type":"string","required":true,"description":"The SDN controller object identifier."},{"name":"type","type":"string","required":true,"description":"Plugin type.","enum":["bgp","evpn","faucet","isis"],"format":"pve-configid"},{"name":"asn","type":"integer","required":false,"description":"autonomous system number","minimum":0,"maximum":4294967295},{"name":"bgp-mode","type":"string","required":false,"description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"default":"auto"},{"name":"bgp-multipath-as-path-relax","type":"boolean","required":false,"description":"Consider different AS paths of equal length for multipath computation."},{"name":"ebgp","type":"boolean","required":false,"description":"Enable eBGP (remote-as external)."},{"name":"ebgp-multihop","type":"integer","required":false,"description":"Set maximum amount of hops for eBGP peers."},{"name":"fabric","type":"string","required":false,"description":"SDN fabric to use as underlay for this EVPN controller.","format":"pve-sdn-fabric-id"},{"name":"isis-domain","type":"string","required":false,"description":"Name of the IS-IS domain."},{"name":"isis-ifaces","type":"string","required":false,"description":"Comma-separated list of interfaces where IS-IS should be active.","format":"pve-iface-list"},{"name":"isis-net","type":"string","required":false,"description":"Network Entity title for this node in the IS-IS network.","format":"pve-sdn-isis-net"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"loopback","type":"string","required":false,"description":"Name of the loopback/dummy interface that provides the Router-IP."},{"name":"node","type":"string","required":false,"description":"The cluster node name.","format":"pve-node"},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"peer-group-name","type":"string","required":false,"description":"Name of the peer group for this EVPN controller","default":"VTEP","format":"pve-configid"},{"name":"peers","type":"string","required":false,"description":"peers address list.","format":"ip-list"},{"name":"route-map-in","type":"string","required":false,"description":"Route Map that should be applied for incoming routes","format":"pve-sdn-route-map-id"},{"name":"route-map-out","type":"string","required":false,"description":"Route Map that should be applied for outgoing routes","format":"pve-sdn-route-map-id"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/controllers\ncluster\ncreate\nCreate a new sdn controller object.\ncontroller string The SDN controller object identifier.\ntype string Plugin type. bgp evpn faucet isis\nasn integer autonomous system number\nbgp-mode string Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. auto external internal\nbgp-multipath-as-path-relax boolean Consider different AS paths of equal length for multipath computation.\nebgp boolean Enable eBGP (remote-as external).\nebgp-multihop integer Set maximum amount of hops for eBGP peers.\nfabric string SDN fabric to use as underlay for this EVPN controller.\nisis-domain string Name of the IS-IS domain.\nisis-ifaces string Comma-separated list of interfaces where IS-IS should be active.\nisis-net string Network Entity title for this node in the IS-IS network.\nlock-token string the token for unlocking the global SDN configuration\nloopback string Name of the loopback/dummy interface that provides the Router-IP.\nnode string The cluster node name.\nnodes string List of cluster node names.\npeer-group-name string Name of the peer group for this EVPN controller\npeers string peers address list.\nroute-map-in string Route Map that should be applied for incoming routes\nroute-map-out string Route Map that should be applied for outgoing routes"} +{"id":"DELETE /cluster/sdn/controllers/{controller}","method":"DELETE","path":"/cluster/sdn/controllers/{controller}","section":"cluster","summary":"delete","description":"Delete sdn controller object configuration.","pathParameters":[{"name":"controller","type":"string","required":true,"description":"The SDN controller object identifier."}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/controllers/{controller}\ncluster\ndelete\nDelete sdn controller object configuration.\ncontroller string The SDN controller object identifier.\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/controllers/{controller}","method":"GET","path":"/cluster/sdn/controllers/{controller}","section":"cluster","summary":"read","description":"Read sdn controller configuration.","pathParameters":[{"name":"controller","type":"string","required":true,"description":"The SDN controller object identifier."}],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"}}},"permissions":{"check":["perm","/sdn/controllers/{controller}",["SDN.Allocate"]]},"raw":{"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"}}}},"searchText":"GET\n/cluster/sdn/controllers/{controller}\ncluster\nread\nRead sdn controller configuration.\ncontroller string The SDN controller object identifier.\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"PUT /cluster/sdn/controllers/{controller}","method":"PUT","path":"/cluster/sdn/controllers/{controller}","section":"cluster","summary":"update","description":"Update sdn controller object configuration.","pathParameters":[{"name":"controller","type":"string","required":true,"description":"The SDN controller object identifier."}],"requestParameters":[{"name":"asn","type":"integer","required":false,"description":"autonomous system number","minimum":0,"maximum":4294967295},{"name":"bgp-mode","type":"string","required":false,"description":"Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP.","enum":["auto","external","internal"],"default":"auto"},{"name":"bgp-multipath-as-path-relax","type":"boolean","required":false,"description":"Consider different AS paths of equal length for multipath computation."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"ebgp","type":"boolean","required":false,"description":"Enable eBGP (remote-as external)."},{"name":"ebgp-multihop","type":"integer","required":false,"description":"Set maximum amount of hops for eBGP peers."},{"name":"fabric","type":"string","required":false,"description":"SDN fabric to use as underlay for this EVPN controller.","format":"pve-sdn-fabric-id"},{"name":"isis-domain","type":"string","required":false,"description":"Name of the IS-IS domain."},{"name":"isis-ifaces","type":"string","required":false,"description":"Comma-separated list of interfaces where IS-IS should be active.","format":"pve-iface-list"},{"name":"isis-net","type":"string","required":false,"description":"Network Entity title for this node in the IS-IS network.","format":"pve-sdn-isis-net"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"loopback","type":"string","required":false,"description":"Name of the loopback/dummy interface that provides the Router-IP."},{"name":"node","type":"string","required":false,"description":"The cluster node name.","format":"pve-node"},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"peer-group-name","type":"string","required":false,"description":"Name of the peer group for this EVPN controller","default":"VTEP","format":"pve-configid"},{"name":"peers","type":"string","required":false,"description":"peers address list.","format":"ip-list"},{"name":"route-map-in","type":"string","required":false,"description":"Route Map that should be applied for incoming routes","format":"pve-sdn-route-map-id"},{"name":"route-map-out","type":"string","required":false,"description":"Route Map that should be applied for outgoing routes","format":"pve-sdn-route-map-id"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/controllers",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/controllers/{controller}\ncluster\nupdate\nUpdate sdn controller object configuration.\ncontroller string The SDN controller object identifier.\nasn integer autonomous system number\nbgp-mode string Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. auto external internal\nbgp-multipath-as-path-relax boolean Consider different AS paths of equal length for multipath computation.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nebgp boolean Enable eBGP (remote-as external).\nebgp-multihop integer Set maximum amount of hops for eBGP peers.\nfabric string SDN fabric to use as underlay for this EVPN controller.\nisis-domain string Name of the IS-IS domain.\nisis-ifaces string Comma-separated list of interfaces where IS-IS should be active.\nisis-net string Network Entity title for this node in the IS-IS network.\nlock-token string the token for unlocking the global SDN configuration\nloopback string Name of the loopback/dummy interface that provides the Router-IP.\nnode string The cluster node name.\nnodes string List of cluster node names.\npeer-group-name string Name of the peer group for this EVPN controller\npeers string peers address list.\nroute-map-in string Route Map that should be applied for incoming routes\nroute-map-out string Route Map that should be applied for outgoing routes"} +{"id":"GET /cluster/sdn/dns","method":"GET","path":"/cluster/sdn/dns","section":"cluster","summary":"index","description":"SDN dns index.","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list sdn dns of specific type","enum":["powerdns"]}],"returns":{"items":{"properties":{"dns":{"type":"string"},"type":{"type":"string"}},"type":"object"},"links":[{"href":"{dns}","rel":"child"}],"type":"array"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/dns\ncluster\nindex\nSDN dns index.\ntype string Only list sdn dns of specific type powerdns"} +{"id":"POST /cluster/sdn/dns","method":"POST","path":"/cluster/sdn/dns","section":"cluster","summary":"create","description":"Create a new sdn dns object.","pathParameters":[],"requestParameters":[{"name":"dns","type":"string","required":true,"description":"The SDN dns object identifier."},{"name":"key","type":"string","required":true},{"name":"type","type":"string","required":true,"description":"Plugin type.","enum":["powerdns"],"format":"pve-configid"},{"name":"url","type":"string","required":true},{"name":"fingerprint","type":"string","required":false,"description":"Certificate SHA 256 fingerprint."},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"reversemaskv6","type":"integer","required":false},{"name":"reversev6mask","type":"integer","required":false},{"name":"ttl","type":"integer","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/dns\ncluster\ncreate\nCreate a new sdn dns object.\ndns string The SDN dns object identifier.\nkey string\ntype string Plugin type. powerdns\nurl string\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nreversemaskv6 integer\nreversev6mask integer\nttl integer"} +{"id":"DELETE /cluster/sdn/dns/{dns}","method":"DELETE","path":"/cluster/sdn/dns/{dns}","section":"cluster","summary":"delete","description":"Delete sdn dns object configuration.","pathParameters":[{"name":"dns","type":"string","required":true,"description":"The SDN dns object identifier."}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/dns/{dns}\ncluster\ndelete\nDelete sdn dns object configuration.\ndns string The SDN dns object identifier.\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/dns/{dns}","method":"GET","path":"/cluster/sdn/dns/{dns}","section":"cluster","summary":"read","description":"Read sdn dns configuration.","pathParameters":[{"name":"dns","type":"string","required":true,"description":"The SDN dns object identifier."}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/sdn/dns/{dns}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/dns/{dns}\ncluster\nread\nRead sdn dns configuration.\ndns string The SDN dns object identifier."} +{"id":"PUT /cluster/sdn/dns/{dns}","method":"PUT","path":"/cluster/sdn/dns/{dns}","section":"cluster","summary":"update","description":"Update sdn dns object configuration.","pathParameters":[{"name":"dns","type":"string","required":true,"description":"The SDN dns object identifier."}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"fingerprint","type":"string","required":false,"description":"Certificate SHA 256 fingerprint."},{"name":"key","type":"string","required":false},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"reversemaskv6","type":"integer","required":false},{"name":"ttl","type":"integer","required":false},{"name":"url","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/dns",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/dns/{dns}\ncluster\nupdate\nUpdate sdn dns object configuration.\ndns string The SDN dns object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfingerprint string Certificate SHA 256 fingerprint.\nkey string\nlock-token string the token for unlocking the global SDN configuration\nreversemaskv6 integer\nttl integer\nurl string"} +{"id":"GET /cluster/sdn/dry-run","method":"GET","path":"/cluster/sdn/dry-run","section":"cluster","summary":"dry-run","description":"Dry-run the SDN apply action and return the difference between the current configuration and the pending configuration","pathParameters":[],"requestParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/dry-run\ncluster\ndry-run\nDry-run the SDN apply action and return the difference between the current configuration and the pending configuration\nnode string The cluster node name."} +{"id":"GET /cluster/sdn/fabrics","method":"GET","path":"/cluster/sdn/fabrics","section":"cluster","summary":"index","description":"SDN Fabrics Index","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/sdn/fabrics",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/fabrics\ncluster\nindex\nSDN Fabrics Index"} +{"id":"GET /cluster/sdn/fabrics/all","method":"GET","path":"/cluster/sdn/fabrics/all","section":"cluster","summary":"list_all","description":"SDN Fabrics Index","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"}},"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"},"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"},"raw":{"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"}},"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"}},"searchText":"GET\n/cluster/sdn/fabrics/all\ncluster\nlist_all\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"GET /cluster/sdn/fabrics/fabric","method":"GET","path":"/cluster/sdn/fabrics/fabric","section":"cluster","summary":"index","description":"SDN Fabrics Index","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/fabrics/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/fabrics/fabric\ncluster\nindex\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"POST /cluster/sdn/fabrics/fabric","method":"POST","path":"/cluster/sdn/fabrics/fabric","section":"cluster","summary":"add_fabric","description":"Add a fabric","pathParameters":[],"requestParameters":[{"name":"id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"protocol","type":"string","required":true,"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"]},{"name":"redistribute","type":"array","required":true},{"name":"area","type":"string","required":false,"description":"OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust."},{"name":"csnp_interval","type":"number","required":false,"description":"The csnp_interval property for Openfabric","minimum":1,"maximum":600},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"hello_interval","type":"number","required":false,"description":"The hello_interval property for Openfabric","minimum":1,"maximum":600},{"name":"ip_prefix","type":"string","required":false,"description":"The IP prefix for Node IPs","format":"CIDR"},{"name":"ip6_prefix","type":"string","required":false,"description":"The IP prefix for Node IPs","format":"CIDR"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"persistent_keepalive","type":"number","required":false,"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","minimum":0,"maximum":65535},{"name":"route_filter","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/fabrics",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/fabrics/fabric\ncluster\nadd_fabric\nAdd a fabric\nid string Identifier for SDN fabrics\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nredistribute array\narea string OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.\ncsnp_interval number The csnp_interval property for Openfabric\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nhello_interval number The hello_interval property for Openfabric\nip_prefix string The IP prefix for Node IPs\nip6_prefix string The IP prefix for Node IPs\nlock-token string the token for unlocking the global SDN configuration\npersistent_keepalive number 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\nroute_filter string A prefix list that should be used for filtering routes that are to be installed into the kernel routing table"} +{"id":"DELETE /cluster/sdn/fabrics/fabric/{id}","method":"DELETE","path":"/cluster/sdn/fabrics/fabric/{id}","section":"cluster","summary":"delete_fabric","description":"Add a fabric","pathParameters":[{"name":"id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/fabrics/{id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/fabrics/fabric/{id}\ncluster\ndelete_fabric\nAdd a fabric\nid string Identifier for SDN fabrics"} +{"id":"GET /cluster/sdn/fabrics/fabric/{id}","method":"GET","path":"/cluster/sdn/fabrics/fabric/{id}","section":"cluster","summary":"get_fabric","description":"Update a fabric","pathParameters":[{"name":"id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/fabrics/{id}",["SDN.Audit","SDN.Allocate"],"any",1]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/fabrics/fabric/{id}\ncluster\nget_fabric\nUpdate a fabric\nid string Identifier for SDN fabrics"} +{"id":"PUT /cluster/sdn/fabrics/fabric/{id}","method":"PUT","path":"/cluster/sdn/fabrics/fabric/{id}","section":"cluster","summary":"update_fabric","description":"Update a fabric","pathParameters":[{"name":"id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"}],"requestParameters":[{"name":"delete","type":"array","required":true},{"name":"protocol","type":"string","required":true,"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"]},{"name":"redistribute","type":"array","required":true},{"name":"area","type":"string","required":false,"description":"OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust."},{"name":"csnp_interval","type":"number","required":false,"description":"The csnp_interval property for Openfabric","minimum":1,"maximum":600},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"hello_interval","type":"number","required":false,"description":"The hello_interval property for Openfabric","minimum":1,"maximum":600},{"name":"ip_prefix","type":"string","required":false,"description":"The IP prefix for Node IPs","format":"CIDR"},{"name":"ip6_prefix","type":"string","required":false,"description":"The IP prefix for Node IPs","format":"CIDR"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"persistent_keepalive","type":"number","required":false,"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","minimum":0,"maximum":65535},{"name":"route_filter","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/fabrics/{id}",["SDN.Allocate"]]},"raw":{"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":["hello_interval","csnp_interval","route_filter"],"type":"string"},"optional":1,"type":"array"},{"instance-types":["bgp"],"items":{"enum":["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"}},"searchText":"PUT\n/cluster/sdn/fabrics/fabric/{id}\ncluster\nupdate_fabric\nUpdate a fabric\nid string Identifier for SDN fabrics\ndelete array\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nredistribute array\narea string OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.\ncsnp_interval number The csnp_interval property for Openfabric\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nhello_interval number The hello_interval property for Openfabric\nip_prefix string The IP prefix for Node IPs\nip6_prefix string The IP prefix for Node IPs\nlock-token string the token for unlocking the global SDN configuration\npersistent_keepalive number 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\nroute_filter string A prefix list that should be used for filtering routes that are to be installed into the kernel routing table"} +{"id":"GET /cluster/sdn/fabrics/node","method":"GET","path":"/cluster/sdn/fabrics/node","section":"cluster","summary":"list_nodes","description":"SDN Fabrics Index","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"}},"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"},"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"},"raw":{"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"}},"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"}},"searchText":"GET\n/cluster/sdn/fabrics/node\ncluster\nlist_nodes\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"GET /cluster/sdn/fabrics/node/{fabric_id}","method":"GET","path":"/cluster/sdn/fabrics/node/{fabric_id}","section":"cluster","summary":"list_nodes_fabric","description":"SDN Fabrics Index","pathParameters":[{"name":"fabric_id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"}],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"}},"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"},"permissions":{"check":["perm","/sdn/fabrics/{fabric_id}",["SDN.Audit"]],"description":"Only returns nodes where you have 'Sys.Audit' or 'Sys.Modify' permissions."},"raw":{"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"}},"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"}},"searchText":"GET\n/cluster/sdn/fabrics/node/{fabric_id}\ncluster\nlist_nodes_fabric\nSDN Fabrics Index\nfabric_id string Identifier for SDN fabrics\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"POST /cluster/sdn/fabrics/node/{fabric_id}","method":"POST","path":"/cluster/sdn/fabrics/node/{fabric_id}","section":"cluster","summary":"add_node","description":"Add a node","pathParameters":[{"name":"fabric_id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"}],"requestParameters":[{"name":"interfaces","type":"array","required":true},{"name":"node_id","type":"string","required":true,"description":"Identifier for nodes in an SDN fabric","format":"pve-node"},{"name":"protocol","type":"string","required":true,"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"]},{"name":"allowed_ips","type":"array","required":false,"description":"A list of IPs that are routable via this node in the WireGuard fabric."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"endpoint","type":"string","required":false,"description":"The endpoint used for connecting to this node."},{"name":"ip","type":"string","required":false,"description":"IPv4 address for this node","format":"ipv4"},{"name":"ip6","type":"string","required":false,"description":"IPv6 address for this node","format":"ipv6"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"peers","type":"array","required":false},{"name":"public_key","type":"string","required":false,"description":"The public key for the external node."},{"name":"role","type":"string","required":false,"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"]}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Allocate"]],["perm","/nodes/{node_id}",["Sys.Modify"]]]},"raw":{"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"}},"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"}},"searchText":"POST\n/cluster/sdn/fabrics/node/{fabric_id}\ncluster\nadd_node\nAdd a node\nfabric_id string Identifier for SDN fabrics\ninterfaces array\nnode_id string Identifier for nodes in an SDN fabric\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nallowed_ips array A list of IPs that are routable via this node in the WireGuard fabric.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nendpoint string The endpoint used for connecting to this node.\nip string IPv4 address for this node\nip6 string IPv6 address for this node\nlock-token string the token for unlocking the global SDN configuration\npeers array\npublic_key string The public key for the external node.\nrole string The role of this node in the WireGuard fabric. internal external"} +{"id":"DELETE /cluster/sdn/fabrics/node/{fabric_id}/{node_id}","method":"DELETE","path":"/cluster/sdn/fabrics/node/{fabric_id}/{node_id}","section":"cluster","summary":"delete_node","description":"Add a node","pathParameters":[{"name":"fabric_id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"node_id","type":"string","required":true,"description":"Identifier for nodes in an SDN fabric","format":"pve-node"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Allocate"]],["perm","/nodes/{node_id}",["Sys.Modify"]]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\ndelete_node\nAdd a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric"} +{"id":"GET /cluster/sdn/fabrics/node/{fabric_id}/{node_id}","method":"GET","path":"/cluster/sdn/fabrics/node/{fabric_id}/{node_id}","section":"cluster","summary":"get_node","description":"Get a node","pathParameters":[{"name":"fabric_id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"node_id","type":"string","required":true,"description":"Identifier for nodes in an SDN fabric","format":"pve-node"}],"requestParameters":[],"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"}},"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"}}},"permissions":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Audit","SDN.Allocate"],"any",1],["perm","/nodes/{node_id}",["Sys.Audit","Sys.Modify"],"any",1]]},"raw":{"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"}},"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"}}}},"searchText":"GET\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\nget_node\nGet a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric"} +{"id":"PUT /cluster/sdn/fabrics/node/{fabric_id}/{node_id}","method":"PUT","path":"/cluster/sdn/fabrics/node/{fabric_id}/{node_id}","section":"cluster","summary":"update_node","description":"Update a node","pathParameters":[{"name":"fabric_id","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"node_id","type":"string","required":true,"description":"Identifier for nodes in an SDN fabric","format":"pve-node"}],"requestParameters":[{"name":"delete","type":"array","required":true},{"name":"interfaces","type":"array","required":true},{"name":"protocol","type":"string","required":true,"description":"Type of configuration entry in an SDN Fabric section config","enum":["openfabric","ospf","wireguard","bgp"]},{"name":"allowed_ips","type":"array","required":false,"description":"A list of IPs that are routable via this node in the WireGuard fabric."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"endpoint","type":"string","required":false,"description":"The endpoint used for connecting to this node."},{"name":"ip","type":"string","required":false,"description":"IPv4 address for this node","format":"ipv4"},{"name":"ip6","type":"string","required":false,"description":"IPv6 address for this node","format":"ipv6"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"peers","type":"array","required":false},{"name":"public_key","type":"string","required":false,"description":"The public key for the external node."},{"name":"role","type":"string","required":false,"description":"The role of this node in the WireGuard fabric.","enum":["internal","external"]}],"returns":{"type":"null"},"permissions":{"check":["and",["perm","/sdn/fabrics/{fabric_id}",["SDN.Allocate"]],["perm","/nodes/{node_id}",["Sys.Modify"]]]},"raw":{"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"}},"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"}},"searchText":"PUT\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\nupdate_node\nUpdate a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric\ndelete array\ninterfaces array\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nallowed_ips array A list of IPs that are routable via this node in the WireGuard fabric.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nendpoint string The endpoint used for connecting to this node.\nip string IPv4 address for this node\nip6 string IPv6 address for this node\nlock-token string the token for unlocking the global SDN configuration\npeers array\npublic_key string The public key for the external node.\nrole string The role of this node in the WireGuard fabric. internal external"} +{"id":"GET /cluster/sdn/ipams","method":"GET","path":"/cluster/sdn/ipams","section":"cluster","summary":"index","description":"SDN ipams index.","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list sdn ipams of specific type","enum":["netbox","phpipam","pve"]}],"returns":{"items":{"properties":{"ipam":{"type":"string"},"type":{"type":"string"}},"type":"object"},"links":[{"href":"{ipam}","rel":"child"}],"type":"array"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/ipams\ncluster\nindex\nSDN ipams index.\ntype string Only list sdn ipams of specific type netbox phpipam pve"} +{"id":"POST /cluster/sdn/ipams","method":"POST","path":"/cluster/sdn/ipams","section":"cluster","summary":"create","description":"Create a new sdn ipam object.","pathParameters":[],"requestParameters":[{"name":"ipam","type":"string","required":true,"description":"The SDN ipam object identifier."},{"name":"type","type":"string","required":true,"description":"Plugin type.","enum":["netbox","phpipam","pve"],"format":"pve-configid"},{"name":"fingerprint","type":"string","required":false,"description":"Certificate SHA 256 fingerprint."},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"section","type":"integer","required":false},{"name":"token","type":"string","required":false},{"name":"url","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/ipams\ncluster\ncreate\nCreate a new sdn ipam object.\nipam string The SDN ipam object identifier.\ntype string Plugin type. netbox phpipam pve\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nsection integer\ntoken string\nurl string"} +{"id":"DELETE /cluster/sdn/ipams/{ipam}","method":"DELETE","path":"/cluster/sdn/ipams/{ipam}","section":"cluster","summary":"delete","description":"Delete sdn ipam object configuration.","pathParameters":[{"name":"ipam","type":"string","required":true,"description":"The SDN ipam object identifier."}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/ipams/{ipam}\ncluster\ndelete\nDelete sdn ipam object configuration.\nipam string The SDN ipam object identifier.\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/ipams/{ipam}","method":"GET","path":"/cluster/sdn/ipams/{ipam}","section":"cluster","summary":"read","description":"Read sdn ipam configuration.","pathParameters":[{"name":"ipam","type":"string","required":true,"description":"The SDN ipam object identifier."}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/sdn/ipams/{ipam}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/ipams/{ipam}\ncluster\nread\nRead sdn ipam configuration.\nipam string The SDN ipam object identifier."} +{"id":"PUT /cluster/sdn/ipams/{ipam}","method":"PUT","path":"/cluster/sdn/ipams/{ipam}","section":"cluster","summary":"update","description":"Update sdn ipam object configuration.","pathParameters":[{"name":"ipam","type":"string","required":true,"description":"The SDN ipam object identifier."}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"fingerprint","type":"string","required":false,"description":"Certificate SHA 256 fingerprint."},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"section","type":"integer","required":false},{"name":"token","type":"string","required":false},{"name":"url","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/ipams",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/ipams/{ipam}\ncluster\nupdate\nUpdate sdn ipam object configuration.\nipam string The SDN ipam object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nsection integer\ntoken string\nurl string"} +{"id":"GET /cluster/sdn/ipams/{ipam}/status","method":"GET","path":"/cluster/sdn/ipams/{ipam}/status","section":"cluster","summary":"ipamindex","description":"List PVE IPAM Entries","pathParameters":[{"name":"ipam","type":"string","required":true,"description":"The SDN ipam object identifier."}],"requestParameters":[],"returns":{"type":"array"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/ipams/{ipam}/status\ncluster\nipamindex\nList PVE IPAM Entries\nipam string The SDN ipam object identifier."} +{"id":"DELETE /cluster/sdn/lock","method":"DELETE","path":"/cluster/sdn/lock","section":"cluster","summary":"release_lock","description":"Release global lock for SDN configuration","pathParameters":[],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"if true, allow releasing lock without providing the token","default":0},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/lock\ncluster\nrelease_lock\nRelease global lock for SDN configuration\nforce boolean if true, allow releasing lock without providing the token\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"POST /cluster/sdn/lock","method":"POST","path":"/cluster/sdn/lock","section":"cluster","summary":"lock","description":"Acquire global lock for SDN configuration","pathParameters":[],"requestParameters":[{"name":"allow-pending","type":"boolean","required":false,"description":"if true, allow acquiring lock even though there are pending changes","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/sdn",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/lock\ncluster\nlock\nAcquire global lock for SDN configuration\nallow-pending boolean if true, allow acquiring lock even though there are pending changes"} +{"id":"GET /cluster/sdn/prefix-lists","method":"GET","path":"/cluster/sdn/prefix-lists","section":"cluster","summary":"list_prefix_lists","description":"List Prefix Lists","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."},{"name":"verbose","type":"boolean","required":false,"description":"If 0, only returns id - otherwise returns all properties."}],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{id}","rel":"child"}],"type":"array"},"permissions":{"description":"Only returns prefix list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/prefix-lists\ncluster\nlist_prefix_lists\nList Prefix Lists\npending boolean Display pending config.\nrunning boolean Display running config.\nverbose boolean If 0, only returns id - otherwise returns all properties."} +{"id":"POST /cluster/sdn/prefix-lists","method":"POST","path":"/cluster/sdn/prefix-lists","section":"cluster","summary":"create_prefix_list_entry","description":"Create Prefix List","pathParameters":[],"requestParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"entries","type":"array","required":false},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/prefix-lists",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/prefix-lists\ncluster\ncreate_prefix_list_entry\nCreate Prefix List\nid string The SDN prefix list identifier\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nentries array\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"DELETE /cluster/sdn/prefix-lists/{id}","method":"DELETE","path":"/cluster/sdn/prefix-lists/{id}","section":"cluster","summary":"delete_prefix_list","description":"Delete Prefix List","pathParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/prefix-lists/{id}\ncluster\ndelete_prefix_list\nDelete Prefix List\nid string The SDN prefix list identifier\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/prefix-lists/{id}","method":"GET","path":"/cluster/sdn/prefix-lists/{id}","section":"cluster","summary":"get_prefix_list","description":"Get Prefix List","pathParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/prefix-lists/{id}\ncluster\nget_prefix_list\nGet Prefix List\nid string The SDN prefix list identifier"} +{"id":"PUT /cluster/sdn/prefix-lists/{id}","method":"PUT","path":"/cluster/sdn/prefix-lists/{id}","section":"cluster","summary":"update_prefix_list","description":"Update Prefix List","pathParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"}],"requestParameters":[{"name":"delete","type":"array","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"entries","type":"array","required":false},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/prefix-lists/{id}\ncluster\nupdate_prefix_list\nUpdate Prefix List\nid string The SDN prefix list identifier\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nentries array\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/prefix-lists/{id}/entries","method":"GET","path":"/cluster/sdn/prefix-lists/{id}/entries","section":"cluster","summary":"get_prefix_list_entries","description":"List Prefix List Entries","pathParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{seq}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/prefix-lists/{id}/entries\ncluster\nget_prefix_list_entries\nList Prefix List Entries\nid string The SDN prefix list identifier"} +{"id":"POST /cluster/sdn/prefix-lists/{id}/entries","method":"POST","path":"/cluster/sdn/prefix-lists/{id}/entries","section":"cluster","summary":"create_prefix_list_entry","description":"Create Prefix List Entry","pathParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"}],"requestParameters":[{"name":"action","type":"string","required":true,"enum":["permit","deny"]},{"name":"prefix","type":"string","required":true,"format":"FullRangeCIDR"},{"name":"ge","type":"integer","required":false,"minimum":0,"maximum":128},{"name":"le","type":"integer","required":false,"minimum":0,"maximum":128},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"seq","type":"integer","required":false,"minimum":1,"maximum":4294967295}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/prefix-lists/{id}/entries\ncluster\ncreate_prefix_list_entry\nCreate Prefix List Entry\nid string The SDN prefix list identifier\naction string permit deny\nprefix string\nge integer\nle integer\nlock-token string the token for unlocking the global SDN configuration\nseq integer"} +{"id":"DELETE /cluster/sdn/prefix-lists/{id}/entries/{url_seq}","method":"DELETE","path":"/cluster/sdn/prefix-lists/{id}/entries/{url_seq}","section":"cluster","summary":"delete_prefix_list_entry","description":"Delete Prefix List Entry","pathParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\ndelete_prefix_list_entry\nDelete Prefix List Entry\nid string The SDN prefix list identifier\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/prefix-lists/{id}/entries/{url_seq}","method":"GET","path":"/cluster/sdn/prefix-lists/{id}/entries/{url_seq}","section":"cluster","summary":"get_prefix_list_entry","description":"Get Prefix List Entry","pathParameters":[{"name":"id","type":"string","required":true,"description":"The SDN prefix list identifier","format":"pve-sdn-prefix-list-id"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\nget_prefix_list_entry\nGet Prefix List Entry\nid string The SDN prefix list identifier"} +{"id":"PUT /cluster/sdn/prefix-lists/{id}/entries/{url_seq}","method":"PUT","path":"/cluster/sdn/prefix-lists/{id}/entries/{url_seq}","section":"cluster","summary":"update_prefix_list_entry","description":"Update Prefix List Entry","pathParameters":[],"requestParameters":[{"name":"action","type":"string","required":false,"enum":["permit","deny"]},{"name":"delete","type":"array","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"ge","type":"integer","required":false,"minimum":0,"maximum":128},{"name":"le","type":"integer","required":false,"minimum":0,"maximum":128},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"prefix","type":"string","required":false,"format":"FullRangeCIDR"},{"name":"seq","type":"integer","required":false,"minimum":1,"maximum":4294967295}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/prefix-lists/{id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\nupdate_prefix_list_entry\nUpdate Prefix List Entry\naction string permit deny\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nge integer\nle integer\nlock-token string the token for unlocking the global SDN configuration\nprefix string\nseq integer"} +{"id":"POST /cluster/sdn/rollback","method":"POST","path":"/cluster/sdn/rollback","section":"cluster","summary":"rollback","description":"Rollback pending changes to SDN configuration","pathParameters":[],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"release-lock","type":"boolean","required":false,"description":"When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards","default":1}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/rollback\ncluster\nrollback\nRollback pending changes to SDN configuration\nlock-token string the token for unlocking the global SDN configuration\nrelease-lock boolean When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards"} +{"id":"GET /cluster/sdn/route-maps","method":"GET","path":"/cluster/sdn/route-maps","section":"cluster","summary":"list_route_maps","description":"List Route Maps","pathParameters":[],"requestParameters":[{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"},"permissions":{"description":"Only returns route maps where you have 'SDN.Audit' or 'SDN.Allocate' permissions.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/route-maps\ncluster\nlist_route_maps\nList Route Maps\nrunning boolean Display running config."} +{"id":"GET /cluster/sdn/route-maps/entries","method":"GET","path":"/cluster/sdn/route-maps/entries","section":"cluster","summary":"list_route_map_entries","description":"Lists all route map entries.","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"},"permissions":{"description":"Only returns route map entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/route-maps/entries\ncluster\nlist_route_map_entries\nLists all route map entries.\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"POST /cluster/sdn/route-maps/entries","method":"POST","path":"/cluster/sdn/route-maps/entries","section":"cluster","summary":"create_route_map_entry","description":"Create Route Map entry","pathParameters":[],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Matching policy of a route map entry.","enum":["permit","deny"]},{"name":"order","type":"integer","required":true,"description":"The index of this route map entry","minimum":0,"maximum":65535},{"name":"route-map-id","type":"string","required":true,"description":"The SDN route map identifier","format":"pve-sdn-route-map-id"},{"name":"call","type":"string","required":false,"description":"The SDN route map identifier","format":"pve-sdn-route-map-id"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"exit-action","type":"string","required":false},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"match","type":"array","required":false},{"name":"set","type":"array","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/route-maps",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/route-maps/entries\ncluster\ncreate_route_map_entry\nCreate Route Map entry\naction string Matching policy of a route map entry. permit deny\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\ncall string The SDN route map identifier\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nexit-action string\nlock-token string the token for unlocking the global SDN configuration\nmatch array\nset array"} +{"id":"GET /cluster/sdn/route-maps/entries/{route-map-id}","method":"GET","path":"/cluster/sdn/route-maps/entries/{route-map-id}","section":"cluster","summary":"list_route_map_entries_for_route_map","description":"List all entries for a given Route Map","pathParameters":[{"name":"route-map-id","type":"string","required":true,"description":"The SDN route map identifier","format":"pve-sdn-route-map-id"}],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"},"permissions":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Audit","SDN.Allocate"],"any",1]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/route-maps/entries/{route-map-id}\ncluster\nlist_route_map_entries_for_route_map\nList all entries for a given Route Map\nroute-map-id string The SDN route map identifier\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"DELETE /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}","method":"DELETE","path":"/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}","section":"cluster","summary":"delete_route_map_entry","description":"Delete Route Map Entry","pathParameters":[{"name":"order","type":"integer","required":true,"description":"The index of this route map entry","minimum":0,"maximum":65535},{"name":"route-map-id","type":"string","required":true,"description":"The SDN route map identifier","format":"pve-sdn-route-map-id"}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\ndelete_route_map_entry\nDelete Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}","method":"GET","path":"/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}","section":"cluster","summary":"get_route_map_entry","description":"Get Route Map Entry","pathParameters":[{"name":"order","type":"integer","required":true,"description":"The index of this route map entry","minimum":0,"maximum":65535},{"name":"route-map-id","type":"string","required":true,"description":"The SDN route map identifier","format":"pve-sdn-route-map-id"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Audit","SDN.Allocate"],"any",1]},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\nget_route_map_entry\nGet Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier"} +{"id":"PUT /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}","method":"PUT","path":"/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}","section":"cluster","summary":"update_route_map_entry","description":"Update Route Map Entry","pathParameters":[{"name":"order","type":"integer","required":true,"description":"The index of this route map entry","minimum":0,"maximum":65535},{"name":"route-map-id","type":"string","required":true,"description":"The SDN route map identifier","format":"pve-sdn-route-map-id"}],"requestParameters":[{"name":"action","type":"string","required":false,"description":"Matching policy of a route map entry.","enum":["permit","deny"]},{"name":"call","type":"string","required":false,"description":"The SDN route map identifier","format":"pve-sdn-route-map-id"},{"name":"delete","type":"array","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"exit-action","type":"string","required":false},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"match","type":"array","required":false},{"name":"set","type":"array","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/route-maps/{route-map-id}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\nupdate_route_map_entry\nUpdate Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\naction string Matching policy of a route map entry. permit deny\ncall string The SDN route map identifier\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nexit-action string\nlock-token string the token for unlocking the global SDN configuration\nmatch array\nset array"} +{"id":"GET /cluster/sdn/vnets","method":"GET","path":"/cluster/sdn/vnets","section":"cluster","summary":"index","description":"SDN vnets index.","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/vnets\ncluster\nindex\nSDN vnets index.\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"POST /cluster/sdn/vnets","method":"POST","path":"/cluster/sdn/vnets","section":"cluster","summary":"create","description":"Create a new sdn vnet object.","pathParameters":[],"requestParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."},{"name":"zone","type":"string","required":true,"description":"Name of the zone this VNet belongs to."},{"name":"alias","type":"string","required":false,"description":"Alias name of the VNet."},{"name":"isolate-ports","type":"boolean","required":false,"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet."},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"tag","type":"integer","required":false,"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","minimum":1,"maximum":16777215},{"name":"type","type":"string","required":false,"description":"Type of the VNet.","enum":["vnet"]},{"name":"vlanaware","type":"boolean","required":false,"description":"Allow VLANs to pass through this vnet."}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/vnets\ncluster\ncreate\nCreate a new sdn vnet object.\nvnet string The SDN vnet object identifier.\nzone string Name of the zone this VNet belongs to.\nalias string Alias name of the VNet.\nisolate-ports boolean If true, sets the isolated property for all interfaces on the bridge of this VNet.\nlock-token string the token for unlocking the global SDN configuration\ntag integer VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).\ntype string Type of the VNet. vnet\nvlanaware boolean Allow VLANs to pass through this vnet."} +{"id":"DELETE /cluster/sdn/vnets/{vnet}","method":"DELETE","path":"/cluster/sdn/vnets/{vnet}","section":"cluster","summary":"delete","description":"Delete sdn vnet object configuration.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/vnets/{vnet}\ncluster\ndelete\nDelete sdn vnet object configuration.\nvnet string The SDN vnet object identifier.\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/vnets/{vnet}","method":"GET","path":"/cluster/sdn/vnets/{vnet}","section":"cluster","summary":"read","description":"Read sdn vnet configuration.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"}}},"permissions":{"description":"Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}}}},"searchText":"GET\n/cluster/sdn/vnets/{vnet}\ncluster\nread\nRead sdn vnet configuration.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"PUT /cluster/sdn/vnets/{vnet}","method":"PUT","path":"/cluster/sdn/vnets/{vnet}","section":"cluster","summary":"update","description":"Update sdn vnet object configuration.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"alias","type":"string","required":false,"description":"Alias name of the VNet."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"isolate-ports","type":"boolean","required":false,"description":"If true, sets the isolated property for all interfaces on the bridge of this VNet."},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"tag","type":"integer","required":false,"description":"VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).","minimum":1,"maximum":16777215},{"name":"vlanaware","type":"boolean","required":false,"description":"Allow VLANs to pass through this vnet."},{"name":"zone","type":"string","required":false,"description":"Name of the zone this VNet belongs to."}],"returns":{"type":"null"},"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/vnets/{vnet}\ncluster\nupdate\nUpdate sdn vnet object configuration.\nvnet string The SDN vnet object identifier.\nalias string Alias name of the VNet.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nisolate-ports boolean If true, sets the isolated property for all interfaces on the bridge of this VNet.\nlock-token string the token for unlocking the global SDN configuration\ntag integer VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).\nvlanaware boolean Allow VLANs to pass through this vnet.\nzone string Name of the zone this VNet belongs to."} +{"id":"GET /cluster/sdn/vnets/{vnet}/firewall","method":"GET","path":"/cluster/sdn/vnets/{vnet}/firewall","section":"cluster","summary":"index","description":"Directory index.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/vnets/{vnet}/firewall\ncluster\nindex\nDirectory index.\nvnet string The SDN vnet object identifier."} +{"id":"GET /cluster/sdn/vnets/{vnet}/firewall/options","method":"GET","path":"/cluster/sdn/vnets/{vnet}/firewall/options","section":"cluster","summary":"get_options","description":"Get vnet firewall options.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[],"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"},"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/vnets/{vnet}/firewall/options\ncluster\nget_options\nGet vnet firewall options.\nvnet string The SDN vnet object identifier."} +{"id":"PUT /cluster/sdn/vnets/{vnet}/firewall/options","method":"PUT","path":"/cluster/sdn/vnets/{vnet}/firewall/options","section":"cluster","summary":"set_options","description":"Set Firewall options.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"enable","type":"boolean","required":false,"description":"Enable/disable firewall rules.","default":0},{"name":"log_level_forward","type":"string","required":false,"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"policy_forward","type":"string","required":false,"description":"Forward policy.","enum":["ACCEPT","DROP"]}],"returns":{"type":"null"},"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/vnets/{vnet}/firewall/options\ncluster\nset_options\nSet Firewall options.\nvnet string The SDN vnet object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nlog_level_forward string Log level for forwarded traffic. emerg alert crit err warning notice info debug nolog\npolicy_forward string Forward policy. ACCEPT DROP"} +{"id":"GET /cluster/sdn/vnets/{vnet}/firewall/rules","method":"GET","path":"/cluster/sdn/vnets/{vnet}/firewall/rules","section":"cluster","summary":"get_rules","description":"List rules.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[],"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"},"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/vnets/{vnet}/firewall/rules\ncluster\nget_rules\nList rules.\nvnet string The SDN vnet object identifier."} +{"id":"POST /cluster/sdn/vnets/{vnet}/firewall/rules","method":"POST","path":"/cluster/sdn/vnets/{vnet}/firewall/rules","section":"cluster","summary":"create_rule","description":"Create new rule.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"type","type":"string","required":true,"description":"Rule type.","enum":["in","out","forward","group"]},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/vnets/{vnet}/firewall/rules\ncluster\ncreate_rule\nCreate new rule.\nvnet string The SDN vnet object identifier.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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."} +{"id":"DELETE /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}","method":"DELETE","path":"/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}","section":"cluster","summary":"delete_rule","description":"Delete rule.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\ndelete_rule\nDelete rule.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}","method":"GET","path":"/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}","section":"cluster","summary":"get_rule","description":"Get single rule data.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[],"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"},"permissions":{"description":"Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\nget_rule\nGet single rule data.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position ."} +{"id":"PUT /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}","method":"PUT","path":"/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}","section":"cluster","summary":"update_rule","description":"Modify rule data.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"action","type":"string","required":false,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"moveto","type":"integer","required":false,"description":"Move rule to new position . Other arguments are ignored.","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"},{"name":"type","type":"string","required":false,"description":"Rule type.","enum":["in","out","forward","group"]}],"returns":{"type":"null"},"permissions":{"description":"Needs SDN.Allocate permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\nupdate_rule\nModify rule data.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group"} +{"id":"DELETE /cluster/sdn/vnets/{vnet}/ips","method":"DELETE","path":"/cluster/sdn/vnets/{vnet}/ips","section":"cluster","summary":"ipdelete","description":"Delete IP Mappings in a VNet","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"ip","type":"string","required":true,"description":"The IP address to delete","format":"ip"},{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."},{"name":"mac","type":"string","required":false,"description":"Unicast MAC address.","format":"mac-addr"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipdelete\nDelete IP Mappings in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to delete\nzone string The SDN zone object identifier.\nmac string Unicast MAC address."} +{"id":"POST /cluster/sdn/vnets/{vnet}/ips","method":"POST","path":"/cluster/sdn/vnets/{vnet}/ips","section":"cluster","summary":"ipcreate","description":"Create IP Mapping in a VNet","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"ip","type":"string","required":true,"description":"The IP address to associate with the given MAC address","format":"ip"},{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."},{"name":"mac","type":"string","required":false,"description":"Unicast MAC address.","format":"mac-addr"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipcreate\nCreate IP Mapping in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to associate with the given MAC address\nzone string The SDN zone object identifier.\nmac string Unicast MAC address."} +{"id":"PUT /cluster/sdn/vnets/{vnet}/ips","method":"PUT","path":"/cluster/sdn/vnets/{vnet}/ips","section":"cluster","summary":"ipupdate","description":"Update IP Mapping in a VNet","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"ip","type":"string","required":true,"description":"The IP address to associate with the given MAC address","format":"ip"},{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."},{"name":"mac","type":"string","required":false,"description":"Unicast MAC address.","format":"mac-addr"},{"name":"vmid","type":"integer","required":false,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/zones/{zone}/{vnet}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipupdate\nUpdate IP Mapping in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to associate with the given MAC address\nzone string The SDN zone object identifier.\nmac string Unicast MAC address.\nvmid integer The (unique) ID of the VM."} +{"id":"GET /cluster/sdn/vnets/{vnet}/subnets","method":"GET","path":"/cluster/sdn/vnets/{vnet}/subnets","section":"cluster","summary":"index","description":"SDN subnets index.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{subnet}","rel":"child"}],"type":"array"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/vnets/{vnet}/subnets\ncluster\nindex\nSDN subnets index.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"POST /cluster/sdn/vnets/{vnet}/subnets","method":"POST","path":"/cluster/sdn/vnets/{vnet}/subnets","section":"cluster","summary":"create","description":"Create a new sdn subnet object.","pathParameters":[{"name":"vnet","type":"string","required":true,"description":"associated vnet"}],"requestParameters":[{"name":"subnet","type":"string","required":true,"description":"The SDN subnet object identifier.","format":"pve-sdn-subnet-id"},{"name":"type","type":"string","required":true,"enum":["subnet"]},{"name":"dhcp-dns-server","type":"string","required":false,"description":"IP address for the DNS server","format":"ip"},{"name":"dhcp-range","type":"array","required":false,"description":"A list of DHCP ranges for this subnet"},{"name":"dnszoneprefix","type":"string","required":false,"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","format":"dns-name"},{"name":"gateway","type":"string","required":false,"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","format":"ip"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"snat","type":"boolean","required":false,"description":"enable masquerade for this subnet if pve-firewall"}],"returns":{"type":"null"},"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/vnets/{vnet}/subnets\ncluster\ncreate\nCreate a new sdn subnet object.\nvnet string associated vnet\nsubnet string The SDN subnet object identifier.\ntype string subnet\ndhcp-dns-server string IP address for the DNS server\ndhcp-range array A list of DHCP ranges for this subnet\ndnszoneprefix string dns domain zone prefix ex: 'adm' -> .adm.mydomain.com\ngateway string Subnet Gateway: Will be assign on vnet for layer3 zones\nlock-token string the token for unlocking the global SDN configuration\nsnat boolean enable masquerade for this subnet if pve-firewall"} +{"id":"DELETE /cluster/sdn/vnets/{vnet}/subnets/{subnet}","method":"DELETE","path":"/cluster/sdn/vnets/{vnet}/subnets/{subnet}","section":"cluster","summary":"delete","description":"Delete sdn subnet object configuration.","pathParameters":[{"name":"subnet","type":"string","required":true,"description":"The SDN subnet object identifier.","format":"pve-sdn-subnet-id"},{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\ndelete\nDelete sdn subnet object configuration.\nsubnet string The SDN subnet object identifier.\nvnet string The SDN vnet object identifier.\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/vnets/{vnet}/subnets/{subnet}","method":"GET","path":"/cluster/sdn/vnets/{vnet}/subnets/{subnet}","section":"cluster","summary":"read","description":"Read sdn subnet configuration.","pathParameters":[{"name":"subnet","type":"string","required":true,"description":"The SDN subnet object identifier.","format":"pve-sdn-subnet-id"},{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"returns":{"type":"object"},"permissions":{"description":"Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\nread\nRead sdn subnet configuration.\nsubnet string The SDN subnet object identifier.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"PUT /cluster/sdn/vnets/{vnet}/subnets/{subnet}","method":"PUT","path":"/cluster/sdn/vnets/{vnet}/subnets/{subnet}","section":"cluster","summary":"update","description":"Update sdn subnet object configuration.","pathParameters":[{"name":"subnet","type":"string","required":true,"description":"The SDN subnet object identifier.","format":"pve-sdn-subnet-id"},{"name":"vnet","type":"string","required":false,"description":"associated vnet"}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dhcp-dns-server","type":"string","required":false,"description":"IP address for the DNS server","format":"ip"},{"name":"dhcp-range","type":"array","required":false,"description":"A list of DHCP ranges for this subnet"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dnszoneprefix","type":"string","required":false,"description":"dns domain zone prefix ex: 'adm' -> .adm.mydomain.com","format":"dns-name"},{"name":"gateway","type":"string","required":false,"description":"Subnet Gateway: Will be assign on vnet for layer3 zones","format":"ip"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"snat","type":"boolean","required":false,"description":"enable masquerade for this subnet if pve-firewall"}],"returns":{"type":"null"},"permissions":{"description":"Require 'SDN.Allocate' permission on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\nupdate\nUpdate sdn subnet object configuration.\nsubnet string The SDN subnet object identifier.\nvnet string associated vnet\ndelete string A list of settings you want to delete.\ndhcp-dns-server string IP address for the DNS server\ndhcp-range array A list of DHCP ranges for this subnet\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndnszoneprefix string dns domain zone prefix ex: 'adm' -> .adm.mydomain.com\ngateway string Subnet Gateway: Will be assign on vnet for layer3 zones\nlock-token string the token for unlocking the global SDN configuration\nsnat boolean enable masquerade for this subnet if pve-firewall"} +{"id":"GET /cluster/sdn/zones","method":"GET","path":"/cluster/sdn/zones","section":"cluster","summary":"index","description":"SDN zones index.","pathParameters":[],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."},{"name":"type","type":"string","required":false,"description":"Only list SDN zones of specific type","enum":["evpn","faucet","qinq","simple","vlan","vxlan"]}],"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"},"permissions":{"description":"Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/sdn/zones\ncluster\nindex\nSDN zones index.\npending boolean Display pending config.\nrunning boolean Display running config.\ntype string Only list SDN zones of specific type evpn faucet qinq simple vlan vxlan"} +{"id":"POST /cluster/sdn/zones","method":"POST","path":"/cluster/sdn/zones","section":"cluster","summary":"create","description":"Create a new sdn zone object.","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":true,"description":"Plugin type.","enum":["evpn","faucet","qinq","simple","vlan","vxlan"],"format":"pve-configid"},{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."},{"name":"advertise-subnets","type":"boolean","required":false,"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes)."},{"name":"bridge","type":"string","required":false,"description":"The bridge for which VLANs should be managed."},{"name":"bridge-disable-mac-learning","type":"boolean","required":false,"description":"Disable auto mac learning."},{"name":"controller","type":"string","required":false,"description":"Controller for this zone."},{"name":"dhcp","type":"string","required":false,"description":"Type of the DHCP backend for this zone","enum":["dnsmasq"]},{"name":"disable-arp-nd-suppression","type":"boolean","required":false,"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages."},{"name":"dns","type":"string","required":false,"description":"dns api server"},{"name":"dnszone","type":"string","required":false,"description":"dns domain zone ex: mydomain.com","format":"dns-name"},{"name":"dp-id","type":"integer","required":false,"description":"Faucet dataplane id"},{"name":"exitnodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"exitnodes-local-routing","type":"boolean","required":false,"description":"Allow exitnodes to connect to EVPN guests."},{"name":"exitnodes-primary","type":"string","required":false,"description":"Force traffic through this exitnode first.","format":"pve-node"},{"name":"fabric","type":"string","required":false,"description":"SDN fabric to use as underlay for this VXLAN zone.","format":"pve-sdn-fabric-id"},{"name":"ipam","type":"string","required":false,"description":"use a specific ipam"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"mac","type":"string","required":false,"description":"Anycast logical router mac address.","format":"mac-addr"},{"name":"mtu","type":"integer","required":false,"description":"MTU of the zone, will be used for the created VNet bridges."},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"peers","type":"string","required":false,"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.","format":"ip-list"},{"name":"reversedns","type":"string","required":false,"description":"reverse dns api server"},{"name":"rt-import","type":"string","required":false,"description":"List of Route Targets that should be imported into the VRF of the zone.","format":"pve-sdn-bgp-rt-list"},{"name":"secondary-controllers","type":"array","required":false,"description":"Additional controllers."},{"name":"tag","type":"integer","required":false,"description":"Service-VLAN Tag (outer VLAN)","minimum":0},{"name":"vlan-protocol","type":"string","required":false,"description":"Which VLAN protocol should be used for the creation of the QinQ zone.","enum":["802.1q","802.1ad"],"default":"802.1q"},{"name":"vrf-vxlan","type":"integer","required":false,"description":"VNI for the zone VRF.","minimum":1,"maximum":16777215},{"name":"vxlan-port","type":"integer","required":false,"description":"UDP port that should be used for the VXLAN tunnel (default 4789).","default":4789,"minimum":1,"maximum":65536}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/zones",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/cluster/sdn/zones\ncluster\ncreate\nCreate a new sdn zone object.\ntype string Plugin type. evpn faucet qinq simple vlan vxlan\nzone string The SDN zone object identifier.\nadvertise-subnets boolean Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).\nbridge string The bridge for which VLANs should be managed.\nbridge-disable-mac-learning boolean Disable auto mac learning.\ncontroller string Controller for this zone.\ndhcp string Type of the DHCP backend for this zone dnsmasq\ndisable-arp-nd-suppression boolean Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.\ndns string dns api server\ndnszone string dns domain zone ex: mydomain.com\ndp-id integer Faucet dataplane id\nexitnodes string List of cluster node names.\nexitnodes-local-routing boolean Allow exitnodes to connect to EVPN guests.\nexitnodes-primary string Force traffic through this exitnode first.\nfabric string SDN fabric to use as underlay for this VXLAN zone.\nipam string use a specific ipam\nlock-token string the token for unlocking the global SDN configuration\nmac string Anycast logical router mac address.\nmtu integer MTU of the zone, will be used for the created VNet bridges.\nnodes string List of cluster node names.\npeers string Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.\nreversedns string reverse dns api server\nrt-import string List of Route Targets that should be imported into the VRF of the zone.\nsecondary-controllers array Additional controllers.\ntag integer Service-VLAN Tag (outer VLAN)\nvlan-protocol string Which VLAN protocol should be used for the creation of the QinQ zone. 802.1q 802.1ad\nvrf-vxlan integer VNI for the zone VRF.\nvxlan-port integer UDP port that should be used for the VXLAN tunnel (default 4789)."} +{"id":"DELETE /cluster/sdn/zones/{zone}","method":"DELETE","path":"/cluster/sdn/zones/{zone}","section":"cluster","summary":"delete","description":"Delete sdn zone object configuration.","pathParameters":[{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."}],"requestParameters":[{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/cluster/sdn/zones/{zone}\ncluster\ndelete\nDelete sdn zone object configuration.\nzone string The SDN zone object identifier.\nlock-token string the token for unlocking the global SDN configuration"} +{"id":"GET /cluster/sdn/zones/{zone}","method":"GET","path":"/cluster/sdn/zones/{zone}","section":"cluster","summary":"read","description":"Read sdn zone configuration.","pathParameters":[{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."}],"requestParameters":[{"name":"pending","type":"boolean","required":false,"description":"Display pending config."},{"name":"running","type":"boolean","required":false,"description":"Display running config."}],"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"}}},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"raw":{"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"}}}},"searchText":"GET\n/cluster/sdn/zones/{zone}\ncluster\nread\nRead sdn zone configuration.\nzone string The SDN zone object identifier.\npending boolean Display pending config.\nrunning boolean Display running config."} +{"id":"PUT /cluster/sdn/zones/{zone}","method":"PUT","path":"/cluster/sdn/zones/{zone}","section":"cluster","summary":"update","description":"Update sdn zone object configuration.","pathParameters":[{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."}],"requestParameters":[{"name":"advertise-subnets","type":"boolean","required":false,"description":"Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes)."},{"name":"bridge","type":"string","required":false,"description":"The bridge for which VLANs should be managed."},{"name":"bridge-disable-mac-learning","type":"boolean","required":false,"description":"Disable auto mac learning."},{"name":"controller","type":"string","required":false,"description":"Controller for this zone."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dhcp","type":"string","required":false,"description":"Type of the DHCP backend for this zone","enum":["dnsmasq"]},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable-arp-nd-suppression","type":"boolean","required":false,"description":"Suppress IPv4 ARP && IPv6 Neighbour Discovery messages."},{"name":"dns","type":"string","required":false,"description":"dns api server"},{"name":"dnszone","type":"string","required":false,"description":"dns domain zone ex: mydomain.com","format":"dns-name"},{"name":"dp-id","type":"integer","required":false,"description":"Faucet dataplane id"},{"name":"exitnodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"exitnodes-local-routing","type":"boolean","required":false,"description":"Allow exitnodes to connect to EVPN guests."},{"name":"exitnodes-primary","type":"string","required":false,"description":"Force traffic through this exitnode first.","format":"pve-node"},{"name":"fabric","type":"string","required":false,"description":"SDN fabric to use as underlay for this VXLAN zone.","format":"pve-sdn-fabric-id"},{"name":"ipam","type":"string","required":false,"description":"use a specific ipam"},{"name":"lock-token","type":"string","required":false,"description":"the token for unlocking the global SDN configuration"},{"name":"mac","type":"string","required":false,"description":"Anycast logical router mac address.","format":"mac-addr"},{"name":"mtu","type":"integer","required":false,"description":"MTU of the zone, will be used for the created VNet bridges."},{"name":"nodes","type":"string","required":false,"description":"List of cluster node names.","format":"pve-node-list"},{"name":"peers","type":"string","required":false,"description":"Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.","format":"ip-list"},{"name":"reversedns","type":"string","required":false,"description":"reverse dns api server"},{"name":"rt-import","type":"string","required":false,"description":"List of Route Targets that should be imported into the VRF of the zone.","format":"pve-sdn-bgp-rt-list"},{"name":"secondary-controllers","type":"array","required":false,"description":"Additional controllers."},{"name":"tag","type":"integer","required":false,"description":"Service-VLAN Tag (outer VLAN)","minimum":0},{"name":"vlan-protocol","type":"string","required":false,"description":"Which VLAN protocol should be used for the creation of the QinQ zone.","enum":["802.1q","802.1ad"],"default":"802.1q"},{"name":"vrf-vxlan","type":"integer","required":false,"description":"VNI for the zone VRF.","minimum":1,"maximum":16777215},{"name":"vxlan-port","type":"integer","required":false,"description":"UDP port that should be used for the VXLAN tunnel (default 4789).","default":4789,"minimum":1,"maximum":65536}],"returns":{"type":"null"},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/cluster/sdn/zones/{zone}\ncluster\nupdate\nUpdate sdn zone object configuration.\nzone string The SDN zone object identifier.\nadvertise-subnets boolean Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).\nbridge string The bridge for which VLANs should be managed.\nbridge-disable-mac-learning boolean Disable auto mac learning.\ncontroller string Controller for this zone.\ndelete string A list of settings you want to delete.\ndhcp string Type of the DHCP backend for this zone dnsmasq\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable-arp-nd-suppression boolean Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.\ndns string dns api server\ndnszone string dns domain zone ex: mydomain.com\ndp-id integer Faucet dataplane id\nexitnodes string List of cluster node names.\nexitnodes-local-routing boolean Allow exitnodes to connect to EVPN guests.\nexitnodes-primary string Force traffic through this exitnode first.\nfabric string SDN fabric to use as underlay for this VXLAN zone.\nipam string use a specific ipam\nlock-token string the token for unlocking the global SDN configuration\nmac string Anycast logical router mac address.\nmtu integer MTU of the zone, will be used for the created VNet bridges.\nnodes string List of cluster node names.\npeers string Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.\nreversedns string reverse dns api server\nrt-import string List of Route Targets that should be imported into the VRF of the zone.\nsecondary-controllers array Additional controllers.\ntag integer Service-VLAN Tag (outer VLAN)\nvlan-protocol string Which VLAN protocol should be used for the creation of the QinQ zone. 802.1q 802.1ad\nvrf-vxlan integer VNI for the zone VRF.\nvxlan-port integer UDP port that should be used for the VXLAN tunnel (default 4789)."} +{"id":"GET /cluster/status","method":"GET","path":"/cluster/status","section":"cluster","summary":"get_status","description":"Get cluster status information.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/cluster/status\ncluster\nget_status\nGet cluster status information."} +{"id":"GET /cluster/tasks","method":"GET","path":"/cluster/tasks","section":"cluster","summary":"tasks","description":"List recent tasks (cluster wide).","pathParameters":[],"requestParameters":[],"returns":{"items":{"properties":{"upid":{"type":"string"}},"type":"object"},"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/cluster/tasks\ncluster\ntasks\nList recent tasks (cluster wide)."} +{"id":"GET /nodes","method":"GET","path":"/nodes","section":"nodes","summary":"index","description":"Cluster node index.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes\nnodes\nindex\nCluster node index."} +{"id":"GET /nodes/{node}","method":"GET","path":"/nodes/{node}","section":"nodes","summary":"index","description":"Node index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}\nnodes\nindex\nNode index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/aplinfo","method":"GET","path":"/nodes/{node}/aplinfo","section":"nodes","summary":"aplinfo","description":"Get list of appliances.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/aplinfo\nnodes\naplinfo\nGet list of appliances.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/aplinfo","method":"POST","path":"/nodes/{node}/aplinfo","section":"nodes","summary":"apl_download","description":"Download appliance templates.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"storage","type":"string","required":true,"description":"The storage where the template will be stored","format":"pve-storage-id"},{"name":"template","type":"string","required":true,"description":"The template which will downloaded"}],"returns":{"type":"string"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/aplinfo\nnodes\napl_download\nDownload appliance templates.\nnode string The cluster node name.\nstorage string The storage where the template will be stored\ntemplate string The template which will downloaded"} +{"id":"GET /nodes/{node}/apt","method":"GET","path":"/nodes/{node}/apt","section":"nodes","summary":"index","description":"Directory index for apt (Advanced Package Tool).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{"id":{"type":"string"}},"type":"object"},"links":[{"href":"{id}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/apt\nnodes\nindex\nDirectory index for apt (Advanced Package Tool).\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/apt/changelog","method":"GET","path":"/nodes/{node}/apt/changelog","section":"nodes","summary":"changelog","description":"Get package changelogs.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"name","type":"string","required":true,"description":"Package name."},{"name":"version","type":"string","required":false,"description":"Package version."}],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/apt/changelog\nnodes\nchangelog\nGet package changelogs.\nnode string The cluster node name.\nname string Package name.\nversion string Package version."} +{"id":"GET /nodes/{node}/apt/repositories","method":"GET","path":"/nodes/{node}/apt/repositories","section":"nodes","summary":"repositories","description":"Get APT repository information.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/apt/repositories\nnodes\nrepositories\nGet APT repository information.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/apt/repositories","method":"POST","path":"/nodes/{node}/apt/repositories","section":"nodes","summary":"change_repository","description":"Change the properties of a repository. Currently only allows enabling/disabling.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"index","type":"integer","required":true,"description":"Index within the file (starting from 0)."},{"name":"path","type":"string","required":true,"description":"Path to the containing file."},{"name":"digest","type":"string","required":false,"description":"Digest to detect modifications."},{"name":"enabled","type":"boolean","required":false,"description":"Whether the repository should be enabled or not."}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/apt/repositories\nnodes\nchange_repository\nChange the properties of a repository. Currently only allows enabling/disabling.\nnode string The cluster node name.\nindex integer Index within the file (starting from 0).\npath string Path to the containing file.\ndigest string Digest to detect modifications.\nenabled boolean Whether the repository should be enabled or not."} +{"id":"PUT /nodes/{node}/apt/repositories","method":"PUT","path":"/nodes/{node}/apt/repositories","section":"nodes","summary":"add_repository","description":"Add a standard repository to the configuration","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"handle","type":"string","required":true,"description":"Handle that identifies a repository."},{"name":"digest","type":"string","required":false,"description":"Digest to detect modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/apt/repositories\nnodes\nadd_repository\nAdd a standard repository to the configuration\nnode string The cluster node name.\nhandle string Handle that identifies a repository.\ndigest string Digest to detect modifications."} +{"id":"GET /nodes/{node}/apt/update","method":"GET","path":"/nodes/{node}/apt/update","section":"nodes","summary":"list_updates","description":"List available updates.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/apt/update\nnodes\nlist_updates\nList available updates.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/apt/update","method":"POST","path":"/nodes/{node}/apt/update","section":"nodes","summary":"update_database","description":"This is used to resynchronize the package index files from their sources (apt-get update).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"notify","type":"boolean","required":false,"description":"Send notification about new packages.","default":0},{"name":"quiet","type":"boolean","required":false,"description":"Only produces output suitable for logging, omitting progress indicators.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/apt/update\nnodes\nupdate_database\nThis is used to resynchronize the package index files from their sources (apt-get update).\nnode string The cluster node name.\nnotify boolean Send notification about new packages.\nquiet boolean Only produces output suitable for logging, omitting progress indicators."} +{"id":"GET /nodes/{node}/apt/versions","method":"GET","path":"/nodes/{node}/apt/versions","section":"nodes","summary":"versions","description":"Get package information for important Proxmox packages.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/apt/versions\nnodes\nversions\nGet package information for important Proxmox packages.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/capabilities","method":"GET","path":"/nodes/{node}/capabilities","section":"nodes","summary":"index","description":"Node capabilities index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/capabilities\nnodes\nindex\nNode capabilities index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/capabilities/qemu","method":"GET","path":"/nodes/{node}/capabilities/qemu","section":"nodes","summary":"qemu_caps_index","description":"QEMU capabilities index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/capabilities/qemu\nnodes\nqemu_caps_index\nQEMU capabilities index.\nnode string The cluster node name.\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /nodes/{node}/capabilities/qemu/cpu","method":"GET","path":"/nodes/{node}/capabilities/qemu/cpu","section":"nodes","summary":"index","description":"List all custom and default CPU models.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"arch","type":"string","required":false,"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"]}],"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"},"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"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/capabilities/qemu/cpu\nnodes\nindex\nList all custom and default CPU models.\nnode string The cluster node name.\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /nodes/{node}/capabilities/qemu/cpu-flags","method":"GET","path":"/nodes/{node}/capabilities/qemu/cpu-flags","section":"nodes","summary":"index","description":"List of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"accel","type":"string","required":false,"description":"Acceleration type to check node compatibility for.","enum":["kvm","tcg"],"default":"kvm"},{"name":"arch","type":"string","required":false,"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"]}],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/capabilities/qemu/cpu-flags\nnodes\nindex\nList of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet.\nnode string The cluster node name.\naccel string Acceleration type to check node compatibility for. kvm tcg\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /nodes/{node}/capabilities/qemu/machines","method":"GET","path":"/nodes/{node}/capabilities/qemu/machines","section":"nodes","summary":"types","description":"Get available QEMU/KVM machine types.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"arch","type":"string","required":false,"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"]}],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/capabilities/qemu/machines\nnodes\ntypes\nGet available QEMU/KVM machine types.\nnode string The cluster node name.\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /nodes/{node}/capabilities/qemu/migration","method":"GET","path":"/nodes/{node}/capabilities/qemu/migration","section":"nodes","summary":"capabilities","description":"Get node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/capabilities/qemu/migration\nnodes\ncapabilities\nGet node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'.\nnode string The cluster node name.\nvm\nvirtual machine\nkvm guest"} +{"id":"GET /nodes/{node}/ceph","method":"GET","path":"/nodes/{node}/ceph","section":"nodes","summary":"index","description":"Directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph\nnodes\nindex\nDirectory index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/ceph/cfg","method":"GET","path":"/nodes/{node}/ceph/cfg","section":"nodes","summary":"index","description":"Directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/cfg\nnodes\nindex\nDirectory index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/ceph/cfg/db","method":"GET","path":"/nodes/{node}/ceph/cfg/db","section":"nodes","summary":"db","description":"Get the Ceph configuration database.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/cfg/db\nnodes\ndb\nGet the Ceph configuration database.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/ceph/cfg/raw","method":"GET","path":"/nodes/{node}/ceph/cfg/raw","section":"nodes","summary":"raw","description":"Get the Ceph configuration file.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/cfg/raw\nnodes\nraw\nGet the Ceph configuration file.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/ceph/cfg/value","method":"GET","path":"/nodes/{node}/ceph/cfg/value","section":"nodes","summary":"value","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.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"config-keys","type":"string","required":true,"description":"List of
: items separated by semicolon, comma or space."}],"returns":{"description":"Two-level map of {section} -> {key} -> value. Underscores in section and key names are normalised to hyphens.","type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/cfg/value\nnodes\nvalue\nGet 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.\nnode string The cluster node name.\nconfig-keys string List of
: items separated by semicolon, comma or space."} +{"id":"GET /nodes/{node}/ceph/cmd-safety","method":"GET","path":"/nodes/{node}/ceph/cmd-safety","section":"nodes","summary":"cmd_safety","description":"Heuristical check if it is safe to perform an action.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Action to check","enum":["stop","destroy"]},{"name":"id","type":"string","required":true,"description":"ID of the service"},{"name":"service","type":"string","required":true,"description":"Service type","enum":["osd","mon","mds"]}],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/cmd-safety\nnodes\ncmd_safety\nHeuristical check if it is safe to perform an action.\nnode string The cluster node name.\naction string Action to check stop destroy\nid string ID of the service\nservice string Service type osd mon mds"} +{"id":"GET /nodes/{node}/ceph/crush","method":"GET","path":"/nodes/{node}/ceph/crush","section":"nodes","summary":"crush","description":"Get OSD crush map","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/crush\nnodes\ncrush\nGet OSD crush map\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/ceph/fs","method":"GET","path":"/nodes/{node}/ceph/fs","section":"nodes","summary":"index","description":"Directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/fs\nnodes\nindex\nDirectory index.\nnode string The cluster node name."} +{"id":"DELETE /nodes/{node}/ceph/fs/{name}","method":"DELETE","path":"/nodes/{node}/ceph/fs/{name}","section":"nodes","summary":"destroyfs","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.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The Ceph filesystem name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"remove-pools","type":"boolean","required":false,"description":"Remove the metadata and data pools used by this filesystem.","default":0},{"name":"remove-storages","type":"boolean","required":false,"description":"Remove pveceph-managed storages configured for this filesystem.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/ceph/fs/{name}\nnodes\ndestroyfs\nDestroy 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.\nname string The Ceph filesystem name.\nnode string The cluster node name.\nremove-pools boolean Remove the metadata and data pools used by this filesystem.\nremove-storages boolean Remove pveceph-managed storages configured for this filesystem."} +{"id":"POST /nodes/{node}/ceph/fs/{name}","method":"POST","path":"/nodes/{node}/ceph/fs/{name}","section":"nodes","summary":"createfs","description":"Create a Ceph filesystem","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"name","type":"string","required":false,"description":"The ceph filesystem name.","default":"cephfs"}],"requestParameters":[{"name":"add-storage","type":"boolean","required":false,"description":"Configure the created CephFS as storage for this cluster.","default":0},{"name":"pg_num","type":"integer","required":false,"description":"Number of placement groups for the backing data pool. The metadata pool will use a quarter of this.","default":128,"minimum":8,"maximum":32768}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/fs/{name}\nnodes\ncreatefs\nCreate a Ceph filesystem\nnode string The cluster node name.\nname string The ceph filesystem name.\nadd-storage boolean Configure the created CephFS as storage for this cluster.\npg_num integer Number of placement groups for the backing data pool. The metadata pool will use a quarter of this."} +{"id":"POST /nodes/{node}/ceph/init","method":"POST","path":"/nodes/{node}/ceph/init","section":"nodes","summary":"init","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.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"cluster-network","type":"string","required":false,"description":"Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it","format":"CIDR"},{"name":"disable_cephx","type":"boolean","required":false,"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!","default":0},{"name":"min_size","type":"integer","required":false,"description":"Minimum number of available replicas per object to allow I/O","default":2,"minimum":1,"maximum":7},{"name":"network","type":"string","required":false,"description":"Use specific network for all ceph related traffic","format":"CIDR"},{"name":"pg_bits","type":"integer","required":false,"description":"Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.","default":6,"minimum":6,"maximum":14},{"name":"size","type":"integer","required":false,"description":"Targeted number of replicas per object","default":3,"minimum":1,"maximum":7}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/init\nnodes\ninit\nCreate 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.\nnode string The cluster node name.\ncluster-network string Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it\ndisable_cephx boolean 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!\nmin_size integer Minimum number of available replicas per object to allow I/O\nnetwork string Use specific network for all ceph related traffic\npg_bits integer Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.\nsize integer Targeted number of replicas per object"} +{"id":"GET /nodes/{node}/ceph/log","method":"GET","path":"/nodes/{node}/ceph/log","section":"nodes","summary":"log","description":"Read ceph log","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"limit","type":"integer","required":false,"description":"Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted.","minimum":0},{"name":"start","type":"integer","required":false,"description":"Offset of the first log line to return (0-based).","minimum":0}],"returns":{"items":{"properties":{"n":{"description":"Log-file line number (1-based).","type":"integer"},"t":{"description":"Log line text.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/log\nnodes\nlog\nRead ceph log\nnode string The cluster node name.\nlimit integer Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted.\nstart integer Offset of the first log line to return (0-based)."} +{"id":"GET /nodes/{node}/ceph/mds","method":"GET","path":"/nodes/{node}/ceph/mds","section":"nodes","summary":"index","description":"MDS directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/mds\nnodes\nindex\nMDS directory index.\nnode string The cluster node name."} +{"id":"DELETE /nodes/{node}/ceph/mds/{name}","method":"DELETE","path":"/nodes/{node}/ceph/mds/{name}","section":"nodes","summary":"destroymds","description":"Destroy Ceph Metadata Server","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name (ID) of the mds"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/ceph/mds/{name}\nnodes\ndestroymds\nDestroy Ceph Metadata Server\nname string The name (ID) of the mds\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/ceph/mds/{name}","method":"POST","path":"/nodes/{node}/ceph/mds/{name}","section":"nodes","summary":"createmds","description":"Create Ceph Metadata Server (MDS)","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"name","type":"string","required":false,"description":"The ID for the mds, when omitted the same as the nodename","default":"nodename"}],"requestParameters":[{"name":"hotstandby","type":"boolean","required":false,"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.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/mds/{name}\nnodes\ncreatemds\nCreate Ceph Metadata Server (MDS)\nnode string The cluster node name.\nname string The ID for the mds, when omitted the same as the nodename\nhotstandby boolean 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."} +{"id":"GET /nodes/{node}/ceph/mgr","method":"GET","path":"/nodes/{node}/ceph/mgr","section":"nodes","summary":"index","description":"MGR directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/mgr\nnodes\nindex\nMGR directory index.\nnode string The cluster node name."} +{"id":"DELETE /nodes/{node}/ceph/mgr/{id}","method":"DELETE","path":"/nodes/{node}/ceph/mgr/{id}","section":"nodes","summary":"destroymgr","description":"Destroy Ceph Manager.","pathParameters":[{"name":"id","type":"string","required":true,"description":"The ID of the manager"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/ceph/mgr/{id}\nnodes\ndestroymgr\nDestroy Ceph Manager.\nid string The ID of the manager\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/ceph/mgr/{id}","method":"POST","path":"/nodes/{node}/ceph/mgr/{id}","section":"nodes","summary":"createmgr","description":"Create Ceph Manager","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"id","type":"string","required":false,"description":"The ID for the manager, when omitted the same as the nodename.","default":"nodename"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/mgr/{id}\nnodes\ncreatemgr\nCreate Ceph Manager\nnode string The cluster node name.\nid string The ID for the manager, when omitted the same as the nodename."} +{"id":"GET /nodes/{node}/ceph/mon","method":"GET","path":"/nodes/{node}/ceph/mon","section":"nodes","summary":"listmon","description":"Get Ceph monitor list.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/mon\nnodes\nlistmon\nGet Ceph monitor list.\nnode string The cluster node name."} +{"id":"DELETE /nodes/{node}/ceph/mon/{monid}","method":"DELETE","path":"/nodes/{node}/ceph/mon/{monid}","section":"nodes","summary":"destroymon","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.","pathParameters":[{"name":"monid","type":"string","required":true,"description":"Monitor ID"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/ceph/mon/{monid}\nnodes\ndestroymon\nDestroy 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.\nmonid string Monitor ID\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/ceph/mon/{monid}","method":"POST","path":"/nodes/{node}/ceph/mon/{monid}","section":"nodes","summary":"createmon","description":"Create a Ceph Monitor. Also auto-creates a Manager for the first monitor.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"monid","type":"string","required":false,"description":"The ID for the monitor, when omitted the same as the nodename.","default":"nodename"}],"requestParameters":[{"name":"mon-address","type":"string","required":false,"description":"Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph.","format":"ip-list"}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/mon/{monid}\nnodes\ncreatemon\nCreate a Ceph Monitor. Also auto-creates a Manager for the first monitor.\nnode string The cluster node name.\nmonid string The ID for the monitor, when omitted the same as the nodename.\nmon-address string Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph."} +{"id":"GET /nodes/{node}/ceph/osd","method":"GET","path":"/nodes/{node}/ceph/osd","section":"nodes","summary":"index","description":"Get Ceph osd list/tree.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/osd\nnodes\nindex\nGet Ceph osd list/tree.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/ceph/osd","method":"POST","path":"/nodes/{node}/ceph/osd","section":"nodes","summary":"createosd","description":"Create OSD","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"dev","type":"string","required":true,"description":"Block device name."},{"name":"crush-device-class","type":"string","required":false,"description":"Set the device class of the OSD in crush."},{"name":"db_dev","type":"string","required":false,"description":"Block device name for block.db."},{"name":"db_dev_size","type":"number","required":false,"description":"Size in GiB for block.db.","minimum":1},{"name":"encrypted","type":"boolean","required":false,"description":"Enables encryption of the OSD.","default":0},{"name":"osds-per-device","type":"integer","required":false,"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},{"name":"wal_dev","type":"string","required":false,"description":"Block device name for block.wal."},{"name":"wal_dev_size","type":"number","required":false,"description":"Size in GiB for block.wal.","minimum":0.5}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/osd\nnodes\ncreateosd\nCreate OSD\nnode string The cluster node name.\ndev string Block device name.\ncrush-device-class string Set the device class of the OSD in crush.\ndb_dev string Block device name for block.db.\ndb_dev_size number Size in GiB for block.db.\nencrypted boolean Enables encryption of the OSD.\nosds-per-device integer OSD services per physical device. Only useful for fast NVMe devices to utilize their performance better. Mutually exclusive with 'db_dev' and 'wal_dev'.\nwal_dev string Block device name for block.wal.\nwal_dev_size number Size in GiB for block.wal."} +{"id":"DELETE /nodes/{node}/ceph/osd/{osdid}","method":"DELETE","path":"/nodes/{node}/ceph/osd/{osdid}","section":"nodes","summary":"destroyosd","description":"Destroy OSD","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"osdid","type":"integer","required":true,"description":"OSD ID"}],"requestParameters":[{"name":"cleanup","type":"boolean","required":false,"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.","default":0}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/ceph/osd/{osdid}\nnodes\ndestroyosd\nDestroy OSD\nnode string The cluster node name.\nosdid integer OSD ID\ncleanup boolean 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."} +{"id":"GET /nodes/{node}/ceph/osd/{osdid}","method":"GET","path":"/nodes/{node}/ceph/osd/{osdid}","section":"nodes","summary":"osdindex","description":"OSD index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"osdid","type":"integer","required":true,"description":"OSD ID"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/osd/{osdid}\nnodes\nosdindex\nOSD index.\nnode string The cluster node name.\nosdid integer OSD ID"} +{"id":"POST /nodes/{node}/ceph/osd/{osdid}/in","method":"POST","path":"/nodes/{node}/ceph/osd/{osdid}/in","section":"nodes","summary":"in","description":"ceph osd in","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"osdid","type":"integer","required":true,"description":"OSD ID"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/osd/{osdid}/in\nnodes\nin\nceph osd in\nnode string The cluster node name.\nosdid integer OSD ID"} +{"id":"GET /nodes/{node}/ceph/osd/{osdid}/lv-info","method":"GET","path":"/nodes/{node}/ceph/osd/{osdid}/lv-info","section":"nodes","summary":"osdvolume","description":"Get OSD volume details","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"osdid","type":"integer","required":true,"description":"OSD ID"}],"requestParameters":[{"name":"type","type":"string","required":false,"description":"OSD device type","enum":["block","db","wal"],"default":"block"}],"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"},"permissions":{"check":["perm","/",["Sys.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/osd/{osdid}/lv-info\nnodes\nosdvolume\nGet OSD volume details\nnode string The cluster node name.\nosdid integer OSD ID\ntype string OSD device type block db wal"} +{"id":"GET /nodes/{node}/ceph/osd/{osdid}/metadata","method":"GET","path":"/nodes/{node}/ceph/osd/{osdid}/metadata","section":"nodes","summary":"osddetails","description":"Get OSD details","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"osdid","type":"integer","required":true,"description":"OSD ID"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/osd/{osdid}/metadata\nnodes\nosddetails\nGet OSD details\nnode string The cluster node name.\nosdid integer OSD ID"} +{"id":"POST /nodes/{node}/ceph/osd/{osdid}/out","method":"POST","path":"/nodes/{node}/ceph/osd/{osdid}/out","section":"nodes","summary":"out","description":"ceph osd out","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"osdid","type":"integer","required":true,"description":"OSD ID"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/osd/{osdid}/out\nnodes\nout\nceph osd out\nnode string The cluster node name.\nosdid integer OSD ID"} +{"id":"POST /nodes/{node}/ceph/osd/{osdid}/scrub","method":"POST","path":"/nodes/{node}/ceph/osd/{osdid}/scrub","section":"nodes","summary":"scrub","description":"Instruct the OSD to scrub.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"osdid","type":"integer","required":true,"description":"OSD ID"}],"requestParameters":[{"name":"deep","type":"boolean","required":false,"description":"If set, instructs a deep scrub instead of a normal one.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/osd/{osdid}/scrub\nnodes\nscrub\nInstruct the OSD to scrub.\nnode string The cluster node name.\nosdid integer OSD ID\ndeep boolean If set, instructs a deep scrub instead of a normal one."} +{"id":"GET /nodes/{node}/ceph/pool","method":"GET","path":"/nodes/{node}/ceph/pool","section":"nodes","summary":"lspools","description":"List all pools and their settings (which are settable by the POST/PUT endpoints).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/pool\nnodes\nlspools\nList all pools and their settings (which are settable by the POST/PUT endpoints).\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/ceph/pool","method":"POST","path":"/nodes/{node}/ceph/pool","section":"nodes","summary":"createpool","description":"Create Ceph pool","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"name","type":"string","required":true,"description":"The name of the pool. It must be unique."},{"name":"add_storages","type":"boolean","required":false,"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).","default":0},{"name":"application","type":"string","required":false,"description":"The application of the pool.","enum":["rbd","cephfs","rgw"],"default":"rbd"},{"name":"crush_rule","type":"string","required":false,"description":"The rule to use for mapping object placement in the cluster."},{"name":"erasure-coding","type":"string","required":false,"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."},{"name":"min_size","type":"integer","required":false,"description":"Minimum number of replicas per object","default":2,"minimum":1,"maximum":7},{"name":"pg_autoscale_mode","type":"string","required":false,"description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"],"default":"warn"},{"name":"pg_num","type":"integer","required":false,"description":"Number of placement groups.","default":128,"minimum":1,"maximum":32768},{"name":"pg_num_min","type":"integer","required":false,"description":"Minimal number of placement groups.","maximum":32768},{"name":"size","type":"integer","required":false,"description":"Number of replicas per object","default":3,"minimum":1,"maximum":7},{"name":"target_size","type":"string","required":false,"description":"The estimated target size of the pool for the PG autoscaler."},{"name":"target_size_ratio","type":"number","required":false,"description":"The estimated target ratio of the pool for the PG autoscaler."}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/pool\nnodes\ncreatepool\nCreate Ceph pool\nnode string The cluster node name.\nname string The name of the pool. It must be unique.\nadd_storages boolean 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).\napplication string The application of the pool. rbd cephfs rgw\ncrush_rule string The rule to use for mapping object placement in the cluster.\nerasure-coding string 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.\nmin_size integer Minimum number of replicas per object\npg_autoscale_mode string The automatic PG scaling mode of the pool. on off warn\npg_num integer Number of placement groups.\npg_num_min integer Minimal number of placement groups.\nsize integer Number of replicas per object\ntarget_size string The estimated target size of the pool for the PG autoscaler.\ntarget_size_ratio number The estimated target ratio of the pool for the PG autoscaler."} +{"id":"DELETE /nodes/{node}/ceph/pool/{name}","method":"DELETE","path":"/nodes/{node}/ceph/pool/{name}","section":"nodes","summary":"destroypool","description":"Destroy pool","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the pool. It must be unique."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"If true, destroys pool even if in use","default":0},{"name":"remove_ecprofile","type":"boolean","required":false,"description":"Remove the erasure code profile. Defaults to true, if applicable.","default":1},{"name":"remove_storages","type":"boolean","required":false,"description":"Remove all pveceph-managed storages configured for this pool","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/ceph/pool/{name}\nnodes\ndestroypool\nDestroy pool\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\nforce boolean If true, destroys pool even if in use\nremove_ecprofile boolean Remove the erasure code profile. Defaults to true, if applicable.\nremove_storages boolean Remove all pveceph-managed storages configured for this pool"} +{"id":"GET /nodes/{node}/ceph/pool/{name}","method":"GET","path":"/nodes/{node}/ceph/pool/{name}","section":"nodes","summary":"poolindex","description":"Pool index.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the pool."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/pool/{name}\nnodes\npoolindex\nPool index.\nname string The name of the pool.\nnode string The cluster node name."} +{"id":"PUT /nodes/{node}/ceph/pool/{name}","method":"PUT","path":"/nodes/{node}/ceph/pool/{name}","section":"nodes","summary":"setpool","description":"Change POOL settings","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the pool. It must be unique."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"application","type":"string","required":false,"description":"The application of the pool.","enum":["rbd","cephfs","rgw"]},{"name":"crush_rule","type":"string","required":false,"description":"The rule to use for mapping object placement in the cluster."},{"name":"min_size","type":"integer","required":false,"description":"Minimum number of replicas per object","minimum":1,"maximum":7},{"name":"pg_autoscale_mode","type":"string","required":false,"description":"The automatic PG scaling mode of the pool.","enum":["on","off","warn"]},{"name":"pg_num","type":"integer","required":false,"description":"Number of placement groups.","minimum":1,"maximum":32768},{"name":"pg_num_min","type":"integer","required":false,"description":"Minimal number of placement groups.","maximum":32768},{"name":"size","type":"integer","required":false,"description":"Number of replicas per object","minimum":1,"maximum":7},{"name":"target_size","type":"string","required":false,"description":"The estimated target size of the pool for the PG autoscaler."},{"name":"target_size_ratio","type":"number","required":false,"description":"The estimated target ratio of the pool for the PG autoscaler."}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/ceph/pool/{name}\nnodes\nsetpool\nChange POOL settings\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\napplication string The application of the pool. rbd cephfs rgw\ncrush_rule string The rule to use for mapping object placement in the cluster.\nmin_size integer Minimum number of replicas per object\npg_autoscale_mode string The automatic PG scaling mode of the pool. on off warn\npg_num integer Number of placement groups.\npg_num_min integer Minimal number of placement groups.\nsize integer Number of replicas per object\ntarget_size string The estimated target size of the pool for the PG autoscaler.\ntarget_size_ratio number The estimated target ratio of the pool for the PG autoscaler."} +{"id":"GET /nodes/{node}/ceph/pool/{name}/status","method":"GET","path":"/nodes/{node}/ceph/pool/{name}/status","section":"nodes","summary":"getpool","description":"Show the current pool status.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The name of the pool. It must be unique."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"verbose","type":"boolean","required":false,"description":"If enabled, will display additional data(eg. statistics).","default":0}],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/pool/{name}/status\nnodes\ngetpool\nShow the current pool status.\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\nverbose boolean If enabled, will display additional data(eg. statistics)."} +{"id":"POST /nodes/{node}/ceph/restart","method":"POST","path":"/nodes/{node}/ceph/restart","section":"nodes","summary":"restart","description":"Restart ceph services.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"service","type":"string","required":false,"description":"Ceph service name.","default":"ceph.target"}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/restart\nnodes\nrestart\nRestart ceph services.\nnode string The cluster node name.\nservice string Ceph service name."} +{"id":"GET /nodes/{node}/ceph/rules","method":"GET","path":"/nodes/{node}/ceph/rules","section":"nodes","summary":"rules","description":"List ceph rules.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{"name":{"description":"Name of the CRUSH rule.","type":"string"}},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/rules\nnodes\nrules\nList ceph rules.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/ceph/start","method":"POST","path":"/nodes/{node}/ceph/start","section":"nodes","summary":"start","description":"Start ceph services.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"service","type":"string","required":false,"description":"Ceph service name.","default":"ceph.target"}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/start\nnodes\nstart\nStart ceph services.\nnode string The cluster node name.\nservice string Ceph service name."} +{"id":"GET /nodes/{node}/ceph/status","method":"GET","path":"/nodes/{node}/ceph/status","section":"nodes","summary":"status","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.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit","Datastore.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/ceph/status\nnodes\nstatus\nGet 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.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/ceph/stop","method":"POST","path":"/nodes/{node}/ceph/stop","section":"nodes","summary":"stop","description":"Stop ceph services.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"service","type":"string","required":false,"description":"Ceph service name.","default":"ceph.target"}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/ceph/stop\nnodes\nstop\nStop ceph services.\nnode string The cluster node name.\nservice string Ceph service name."} +{"id":"GET /nodes/{node}/certificates","method":"GET","path":"/nodes/{node}/certificates","section":"nodes","summary":"index","description":"Node index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/certificates\nnodes\nindex\nNode index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/certificates/acme","method":"GET","path":"/nodes/{node}/certificates/acme","section":"nodes","summary":"index","description":"ACME index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/certificates/acme\nnodes\nindex\nACME index.\nnode string The cluster node name."} +{"id":"DELETE /nodes/{node}/certificates/acme/certificate","method":"DELETE","path":"/nodes/{node}/certificates/acme/certificate","section":"nodes","summary":"revoke_certificate","description":"Revoke existing certificate from CA.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/certificates/acme/certificate\nnodes\nrevoke_certificate\nRevoke existing certificate from CA.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/certificates/acme/certificate","method":"POST","path":"/nodes/{node}/certificates/acme/certificate","section":"nodes","summary":"new_certificate","description":"Order a new certificate from ACME-compatible CA.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Overwrite existing custom certificate.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/certificates/acme/certificate\nnodes\nnew_certificate\nOrder a new certificate from ACME-compatible CA.\nnode string The cluster node name.\nforce boolean Overwrite existing custom certificate."} +{"id":"PUT /nodes/{node}/certificates/acme/certificate","method":"PUT","path":"/nodes/{node}/certificates/acme/certificate","section":"nodes","summary":"renew_certificate","description":"Renew existing certificate from CA.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Force renewal even if expiry is more than 30 days away.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/certificates/acme/certificate\nnodes\nrenew_certificate\nRenew existing certificate from CA.\nnode string The cluster node name.\nforce boolean Force renewal even if expiry is more than 30 days away."} +{"id":"DELETE /nodes/{node}/certificates/custom","method":"DELETE","path":"/nodes/{node}/certificates/custom","section":"nodes","summary":"remove_custom_cert","description":"DELETE custom certificate chain and key.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"restart","type":"boolean","required":false,"description":"Restart pveproxy.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/certificates/custom\nnodes\nremove_custom_cert\nDELETE custom certificate chain and key.\nnode string The cluster node name.\nrestart boolean Restart pveproxy."} +{"id":"POST /nodes/{node}/certificates/custom","method":"POST","path":"/nodes/{node}/certificates/custom","section":"nodes","summary":"upload_custom_cert","description":"Upload or update custom certificate chain and key.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"certificates","type":"string","required":true,"description":"PEM encoded certificate (chain).","format":"pem-certificate-chain"},{"name":"force","type":"boolean","required":false,"description":"Overwrite existing custom or ACME certificate files.","default":0},{"name":"key","type":"string","required":false,"description":"PEM encoded private key.","format":"pem-string"},{"name":"restart","type":"boolean","required":false,"description":"Restart pveproxy.","default":0}],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/certificates/custom\nnodes\nupload_custom_cert\nUpload or update custom certificate chain and key.\nnode string The cluster node name.\ncertificates string PEM encoded certificate (chain).\nforce boolean Overwrite existing custom or ACME certificate files.\nkey string PEM encoded private key.\nrestart boolean Restart pveproxy."} +{"id":"GET /nodes/{node}/certificates/info","method":"GET","path":"/nodes/{node}/certificates/info","section":"nodes","summary":"info","description":"Get information about node's certificates.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/certificates/info\nnodes\ninfo\nGet information about node's certificates.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/config","method":"GET","path":"/nodes/{node}/config","section":"nodes","summary":"get_config","description":"Get node configuration options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"property","type":"string","required":false,"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"],"default":"all"}],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/config\nnodes\nget_config\nGet node configuration options.\nnode string The cluster node name.\nproperty string Return only a specific property from the node configuration. acme acmedomain0 acmedomain1 acmedomain2 acmedomain3 acmedomain4 acmedomain5 ballooning-target description location startall-onboot-delay wakeonlan"} +{"id":"PUT /nodes/{node}/config","method":"PUT","path":"/nodes/{node}/config","section":"nodes","summary":"set_options","description":"Set node configuration options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"acme","type":"string","required":false,"description":"Node specific ACME settings."},{"name":"acmedomain[n]","type":"string","required":false,"description":"ACME domain and validation plugin"},{"name":"ballooning-target","type":"integer","required":false,"description":"RAM usage target for ballooning (in percent of total memory)","default":80,"minimum":0,"maximum":100},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications."},{"name":"location","type":"string","required":false,"description":"The location of the node. Overrides the default from the datacenter config."},{"name":"startall-onboot-delay","type":"integer","required":false,"description":"Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.","default":0,"minimum":0,"maximum":300},{"name":"wakeonlan","type":"string","required":false,"description":"Node specific wake on LAN settings."}],"returns":{"type":"null"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/config\nnodes\nset_options\nSet node configuration options.\nnode string The cluster node name.\nacme string Node specific ACME settings.\nacmedomain[n] string ACME domain and validation plugin\nballooning-target integer RAM usage target for ballooning (in percent of total memory)\ndelete string A list of settings you want to delete.\ndescription string Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nlocation string The location of the node. Overrides the default from the datacenter config.\nstartall-onboot-delay integer Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.\nwakeonlan string Node specific wake on LAN settings."} +{"id":"GET /nodes/{node}/disks","method":"GET","path":"/nodes/{node}/disks","section":"nodes","summary":"index","description":"Node index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks\nnodes\nindex\nNode index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/disks/directory","method":"GET","path":"/nodes/{node}/disks/directory","section":"nodes","summary":"index","description":"PVE Managed Directory storages.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks/directory\nnodes\nindex\nPVE Managed Directory storages.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/disks/directory","method":"POST","path":"/nodes/{node}/disks/directory","section":"nodes","summary":"create","description":"Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"device","type":"string","required":true,"description":"The block device you want to create the filesystem on."},{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"add_storage","type":"boolean","required":false,"description":"Configure storage using the directory.","default":0},{"name":"filesystem","type":"string","required":false,"description":"The desired filesystem.","enum":["ext4","xfs"],"default":"ext4"}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/disks/directory\nnodes\ncreate\nCreate a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.\nnode string The cluster node name.\ndevice string The block device you want to create the filesystem on.\nname string The storage identifier.\nadd_storage boolean Configure storage using the directory.\nfilesystem string The desired filesystem. ext4 xfs"} +{"id":"DELETE /nodes/{node}/disks/directory/{name}","method":"DELETE","path":"/nodes/{node}/disks/directory/{name}","section":"nodes","summary":"delete","description":"Unmounts the storage and removes the mount unit.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"cleanup-config","type":"boolean","required":false,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","default":0},{"name":"cleanup-disks","type":"boolean","required":false,"description":"Also wipe disk so it can be repurposed afterwards.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/disks/directory/{name}\nnodes\ndelete\nUnmounts the storage and removes the mount unit.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disk so it can be repurposed afterwards."} +{"id":"POST /nodes/{node}/disks/initgpt","method":"POST","path":"/nodes/{node}/disks/initgpt","section":"nodes","summary":"initgpt","description":"Initialize Disk with GPT","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"disk","type":"string","required":true,"description":"Block device name"},{"name":"uuid","type":"string","required":false,"description":"UUID for the GPT table"}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/disks/initgpt\nnodes\ninitgpt\nInitialize Disk with GPT\nnode string The cluster node name.\ndisk string Block device name\nuuid string UUID for the GPT table"} +{"id":"GET /nodes/{node}/disks/list","method":"GET","path":"/nodes/{node}/disks/list","section":"nodes","summary":"list","description":"List local disks.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"include-partitions","type":"boolean","required":false,"description":"Also include partitions.","default":0},{"name":"skipsmart","type":"boolean","required":false,"description":"Skip smart checks.","default":0},{"name":"type","type":"string","required":false,"description":"Only list specific types of disks.","enum":["unused","journal_disks"]}],"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"},"permissions":{"check":["or",["perm","/",["Sys.Audit"]],["perm","/nodes/{node}",["Sys.Audit"]]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks/list\nnodes\nlist\nList local disks.\nnode string The cluster node name.\ninclude-partitions boolean Also include partitions.\nskipsmart boolean Skip smart checks.\ntype string Only list specific types of disks. unused journal_disks"} +{"id":"GET /nodes/{node}/disks/lvm","method":"GET","path":"/nodes/{node}/disks/lvm","section":"nodes","summary":"index","description":"List LVM Volume Groups","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks/lvm\nnodes\nindex\nList LVM Volume Groups\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/disks/lvm","method":"POST","path":"/nodes/{node}/disks/lvm","section":"nodes","summary":"create","description":"Create an LVM Volume Group","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"device","type":"string","required":true,"description":"The block device you want to create the volume group on"},{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"add_storage","type":"boolean","required":false,"description":"Configure storage using the Volume Group","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/disks/lvm\nnodes\ncreate\nCreate an LVM Volume Group\nnode string The cluster node name.\ndevice string The block device you want to create the volume group on\nname string The storage identifier.\nadd_storage boolean Configure storage using the Volume Group"} +{"id":"DELETE /nodes/{node}/disks/lvm/{name}","method":"DELETE","path":"/nodes/{node}/disks/lvm/{name}","section":"nodes","summary":"delete","description":"Remove an LVM Volume Group.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"cleanup-config","type":"boolean","required":false,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","default":0},{"name":"cleanup-disks","type":"boolean","required":false,"description":"Also wipe disks so they can be repurposed afterwards.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/disks/lvm/{name}\nnodes\ndelete\nRemove an LVM Volume Group.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards."} +{"id":"GET /nodes/{node}/disks/lvmthin","method":"GET","path":"/nodes/{node}/disks/lvmthin","section":"nodes","summary":"index","description":"List LVM thinpools","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks/lvmthin\nnodes\nindex\nList LVM thinpools\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/disks/lvmthin","method":"POST","path":"/nodes/{node}/disks/lvmthin","section":"nodes","summary":"create","description":"Create an LVM thinpool","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"device","type":"string","required":true,"description":"The block device you want to create the thinpool on."},{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"add_storage","type":"boolean","required":false,"description":"Configure storage using the thinpool.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/disks/lvmthin\nnodes\ncreate\nCreate an LVM thinpool\nnode string The cluster node name.\ndevice string The block device you want to create the thinpool on.\nname string The storage identifier.\nadd_storage boolean Configure storage using the thinpool."} +{"id":"DELETE /nodes/{node}/disks/lvmthin/{name}","method":"DELETE","path":"/nodes/{node}/disks/lvmthin/{name}","section":"nodes","summary":"delete","description":"Remove an LVM thin pool.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"volume-group","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"cleanup-config","type":"boolean","required":false,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","default":0},{"name":"cleanup-disks","type":"boolean","required":false,"description":"Also wipe disks so they can be repurposed afterwards.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/disks/lvmthin/{name}\nnodes\ndelete\nRemove an LVM thin pool.\nname string The storage identifier.\nnode string The cluster node name.\nvolume-group string The storage identifier.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards."} +{"id":"GET /nodes/{node}/disks/smart","method":"GET","path":"/nodes/{node}/disks/smart","section":"nodes","summary":"smart","description":"Get SMART Health of a disk.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"disk","type":"string","required":true,"description":"Block device name"},{"name":"healthonly","type":"boolean","required":false,"description":"If true returns only the health status"}],"returns":{"properties":{"attributes":{"optional":1,"type":"array"},"health":{"type":"string"},"text":{"optional":1,"type":"string"},"type":{"optional":1,"type":"string"}},"type":"object"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks/smart\nnodes\nsmart\nGet SMART Health of a disk.\nnode string The cluster node name.\ndisk string Block device name\nhealthonly boolean If true returns only the health status"} +{"id":"PUT /nodes/{node}/disks/wipedisk","method":"PUT","path":"/nodes/{node}/disks/wipedisk","section":"nodes","summary":"wipe_disk","description":"Wipe a disk or partition.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"disk","type":"string","required":true,"description":"Block device name"}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/disks/wipedisk\nnodes\nwipe_disk\nWipe a disk or partition.\nnode string The cluster node name.\ndisk string Block device name"} +{"id":"GET /nodes/{node}/disks/zfs","method":"GET","path":"/nodes/{node}/disks/zfs","section":"nodes","summary":"index","description":"List Zpools.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks/zfs\nnodes\nindex\nList Zpools.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/disks/zfs","method":"POST","path":"/nodes/{node}/disks/zfs","section":"nodes","summary":"create","description":"Create a ZFS pool.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"devices","type":"string","required":true,"description":"The block devices you want to create the zpool on.","format":"string-list"},{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"raidlevel","type":"string","required":true,"description":"The RAID level to use.","enum":["single","mirror","raid10","raidz","raidz2","raidz3","draid","draid2","draid3"]},{"name":"add_storage","type":"boolean","required":false,"description":"Configure storage using the zpool.","default":0},{"name":"ashift","type":"integer","required":false,"description":"Pool sector size exponent.","default":12,"minimum":9,"maximum":16},{"name":"compression","type":"string","required":false,"description":"The compression algorithm to use.","enum":["on","off","gzip","lz4","lzjb","zle","zstd"],"default":"on"},{"name":"draid-config","type":"string","required":false}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/disks/zfs\nnodes\ncreate\nCreate a ZFS pool.\nnode string The cluster node name.\ndevices string The block devices you want to create the zpool on.\nname string The storage identifier.\nraidlevel string The RAID level to use. single mirror raid10 raidz raidz2 raidz3 draid draid2 draid3\nadd_storage boolean Configure storage using the zpool.\nashift integer Pool sector size exponent.\ncompression string The compression algorithm to use. on off gzip lz4 lzjb zle zstd\ndraid-config string"} +{"id":"DELETE /nodes/{node}/disks/zfs/{name}","method":"DELETE","path":"/nodes/{node}/disks/zfs/{name}","section":"nodes","summary":"delete","description":"Destroy a ZFS pool.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"cleanup-config","type":"boolean","required":false,"description":"Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).","default":0},{"name":"cleanup-disks","type":"boolean","required":false,"description":"Also wipe disks so they can be repurposed afterwards.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/",["Sys.Modify"]],"description":"Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/disks/zfs/{name}\nnodes\ndelete\nDestroy a ZFS pool.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards."} +{"id":"GET /nodes/{node}/disks/zfs/{name}","method":"GET","path":"/nodes/{node}/disks/zfs/{name}","section":"nodes","summary":"detail","description":"Get details about a zpool.","pathParameters":[{"name":"name","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/disks/zfs/{name}\nnodes\ndetail\nGet details about a zpool.\nname string The storage identifier.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/dns","method":"GET","path":"/nodes/{node}/dns","section":"nodes","summary":"dns","description":"Read DNS settings.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/dns\nnodes\ndns\nRead DNS settings.\nnode string The cluster node name."} +{"id":"PUT /nodes/{node}/dns","method":"PUT","path":"/nodes/{node}/dns","section":"nodes","summary":"update_dns","description":"Write DNS settings.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"search","type":"string","required":true,"description":"Search domain for host-name lookup."},{"name":"dns1","type":"string","required":false,"description":"First name server IP address.","format":"ip"},{"name":"dns2","type":"string","required":false,"description":"Second name server IP address.","format":"ip"},{"name":"dns3","type":"string","required":false,"description":"Third name server IP address.","format":"ip"}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/dns\nnodes\nupdate_dns\nWrite DNS settings.\nnode string The cluster node name.\nsearch string Search domain for host-name lookup.\ndns1 string First name server IP address.\ndns2 string Second name server IP address.\ndns3 string Third name server IP address."} +{"id":"POST /nodes/{node}/execute","method":"POST","path":"/nodes/{node}/execute","section":"nodes","summary":"execute","description":"Execute multiple commands in order, root only.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"commands","type":"string","required":true,"description":"JSON encoded array of commands.","format":"pve-command-batch"}],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/execute\nnodes\nexecute\nExecute multiple commands in order, root only.\nnode string The cluster node name.\ncommands string JSON encoded array of commands."} +{"id":"GET /nodes/{node}/firewall","method":"GET","path":"/nodes/{node}/firewall","section":"nodes","summary":"index","description":"Directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/firewall/log","method":"GET","path":"/nodes/{node}/firewall/log","section":"nodes","summary":"log","description":"Read firewall log","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"limit","type":"integer","required":false,"minimum":0},{"name":"since","type":"integer","required":false,"description":"Display log since this UNIX epoch.","minimum":0},{"name":"start","type":"integer","required":false,"minimum":0},{"name":"until","type":"integer","required":false,"description":"Display log until this UNIX epoch.","minimum":0}],"returns":{"items":{"properties":{"n":{"description":"Line number","type":"integer"},"t":{"description":"Line text","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch."} +{"id":"GET /nodes/{node}/firewall/options","method":"GET","path":"/nodes/{node}/firewall/options","section":"nodes","summary":"get_options","description":"Get host firewall options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/firewall/options\nnodes\nget_options\nGet host firewall options.\nnode string The cluster node name."} +{"id":"PUT /nodes/{node}/firewall/options","method":"PUT","path":"/nodes/{node}/firewall/options","section":"nodes","summary":"set_options","description":"Set Firewall options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"enable","type":"boolean","required":false,"description":"Enable host firewall rules.","default":1},{"name":"log_level_forward","type":"string","required":false,"description":"Log level for forwarded traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"log_level_in","type":"string","required":false,"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"log_level_out","type":"string","required":false,"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"log_nf_conntrack","type":"boolean","required":false,"description":"Enable logging of conntrack information.","default":0},{"name":"ndp","type":"boolean","required":false,"description":"Enable NDP (Neighbor Discovery Protocol).","default":1},{"name":"nf_conntrack_allow_invalid","type":"boolean","required":false,"description":"Allow invalid packets on connection tracking.","default":0},{"name":"nf_conntrack_helpers","type":"string","required":false,"description":"Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp","default":"","format":"pve-fw-conntrack-helper"},{"name":"nf_conntrack_max","type":"integer","required":false,"description":"Maximum number of tracked connections.","default":262144,"minimum":32768},{"name":"nf_conntrack_tcp_timeout_established","type":"integer","required":false,"description":"Conntrack established timeout.","default":432000,"minimum":7875},{"name":"nf_conntrack_tcp_timeout_syn_recv","type":"integer","required":false,"description":"Conntrack syn recv timeout.","default":60,"minimum":30,"maximum":60},{"name":"nftables","type":"boolean","required":false,"description":"Enable nftables based firewall (tech preview)","default":0},{"name":"nosmurfs","type":"boolean","required":false,"description":"Enable SMURFS filter."},{"name":"protection_synflood","type":"boolean","required":false,"description":"Enable synflood protection","default":0},{"name":"protection_synflood_burst","type":"integer","required":false,"description":"Synflood protection rate burst by ip src.","default":1000},{"name":"protection_synflood_rate","type":"integer","required":false,"description":"Synflood protection rate syn/sec by ip src.","default":200},{"name":"smurf_log_level","type":"string","required":false,"description":"Log level for SMURFS filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"tcp_flags_log_level","type":"string","required":false,"description":"Log level for illegal tcp flags filter.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"tcpflags","type":"boolean","required":false,"description":"Filter illegal combinations of TCP flags.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable host firewall rules.\nlog_level_forward string Log level for forwarded traffic. emerg alert crit err warning notice info debug nolog\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nlog_nf_conntrack boolean Enable logging of conntrack information.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\nnf_conntrack_allow_invalid boolean Allow invalid packets on connection tracking.\nnf_conntrack_helpers string Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp\nnf_conntrack_max integer Maximum number of tracked connections.\nnf_conntrack_tcp_timeout_established integer Conntrack established timeout.\nnf_conntrack_tcp_timeout_syn_recv integer Conntrack syn recv timeout.\nnftables boolean Enable nftables based firewall (tech preview)\nnosmurfs boolean Enable SMURFS filter.\nprotection_synflood boolean Enable synflood protection\nprotection_synflood_burst integer Synflood protection rate burst by ip src.\nprotection_synflood_rate integer Synflood protection rate syn/sec by ip src.\nsmurf_log_level string Log level for SMURFS filter. emerg alert crit err warning notice info debug nolog\ntcp_flags_log_level string Log level for illegal tcp flags filter. emerg alert crit err warning notice info debug nolog\ntcpflags boolean Filter illegal combinations of TCP flags."} +{"id":"GET /nodes/{node}/firewall/rules","method":"GET","path":"/nodes/{node}/firewall/rules","section":"nodes","summary":"get_rules","description":"List rules.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/firewall/rules","method":"POST","path":"/nodes/{node}/firewall/rules","section":"nodes","summary":"create_rule","description":"Create new rule.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"type","type":"string","required":true,"description":"Rule type.","enum":["in","out","forward","group"]},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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."} +{"id":"DELETE /nodes/{node}/firewall/rules/{pos}","method":"DELETE","path":"/nodes/{node}/firewall/rules/{pos}","section":"nodes","summary":"delete_rule","description":"Delete rule.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /nodes/{node}/firewall/rules/{pos}","method":"GET","path":"/nodes/{node}/firewall/rules/{pos}","section":"nodes","summary":"get_rule","description":"Get single rule data.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\npos integer Update rule at position ."} +{"id":"PUT /nodes/{node}/firewall/rules/{pos}","method":"PUT","path":"/nodes/{node}/firewall/rules/{pos}","section":"nodes","summary":"update_rule","description":"Modify rule data.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"action","type":"string","required":false,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"moveto","type":"integer","required":false,"description":"Move rule to new position . Other arguments are ignored.","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"},{"name":"type","type":"string","required":false,"description":"Rule type.","enum":["in","out","forward","group"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group"} +{"id":"GET /nodes/{node}/hardware","method":"GET","path":"/nodes/{node}/hardware","section":"nodes","summary":"index","description":"Index of hardware types","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{"type":{"type":"string"}},"type":"object"},"links":[{"href":"{type}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/hardware\nnodes\nindex\nIndex of hardware types\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/hardware/pci","method":"GET","path":"/nodes/{node}/hardware/pci","section":"nodes","summary":"pci_scan","description":"List local PCI devices.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"pci-class-blacklist","type":"string","required":false,"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).","default":"05;06;0b","format":"string-list"},{"name":"verbose","type":"boolean","required":false,"description":"If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned.","default":1}],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/hardware/pci\nnodes\npci_scan\nList local PCI devices.\nnode string The cluster node name.\npci-class-blacklist string A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).\nverbose boolean If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned."} +{"id":"GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}","method":"GET","path":"/nodes/{node}/hardware/pci/{pci-id-or-mapping}","section":"nodes","summary":"pci_index","description":"Index of available pci methods","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"pci-id-or-mapping","type":"string","required":true}],"requestParameters":[],"returns":{"items":{"properties":{"method":{"type":"string"}},"type":"object"},"links":[{"href":"{method}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/hardware/pci/{pci-id-or-mapping}\nnodes\npci_index\nIndex of available pci methods\nnode string The cluster node name.\npci-id-or-mapping string"} +{"id":"GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev","method":"GET","path":"/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev","section":"nodes","summary":"mdevscan","description":"List mediated device types for given PCI device.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"pci-id-or-mapping","type":"string","required":true,"description":"The PCI ID or mapping to list the mdev types for."}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit","Sys.Modify"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev\nnodes\nmdevscan\nList mediated device types for given PCI device.\nnode string The cluster node name.\npci-id-or-mapping string The PCI ID or mapping to list the mdev types for."} +{"id":"GET /nodes/{node}/hardware/usb","method":"GET","path":"/nodes/{node}/hardware/usb","section":"nodes","summary":"usbscan","description":"List local USB devices.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Modify"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/hardware/usb\nnodes\nusbscan\nList local USB devices.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/hosts","method":"GET","path":"/nodes/{node}/hosts","section":"nodes","summary":"get_etc_hosts","description":"Get the content of /etc/hosts.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/hosts\nnodes\nget_etc_hosts\nGet the content of /etc/hosts.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/hosts","method":"POST","path":"/nodes/{node}/hosts","section":"nodes","summary":"write_etc_hosts","description":"Write /etc/hosts.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"data","type":"string","required":true,"description":"The target content of /etc/hosts."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/hosts\nnodes\nwrite_etc_hosts\nWrite /etc/hosts.\nnode string The cluster node name.\ndata string The target content of /etc/hosts.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."} +{"id":"GET /nodes/{node}/journal","method":"GET","path":"/nodes/{node}/journal","section":"nodes","summary":"journal","description":"Read Journal","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"endcursor","type":"string","required":false,"description":"End before the given Cursor. Conflicts with 'until'"},{"name":"lastentries","type":"integer","required":false,"description":"Limit to the last X lines. Conflicts with a range.","minimum":0},{"name":"since","type":"integer","required":false,"description":"Display all log since this UNIX epoch. Conflicts with 'startcursor'.","minimum":0},{"name":"startcursor","type":"string","required":false,"description":"Start after the given Cursor. Conflicts with 'since'"},{"name":"until","type":"integer","required":false,"description":"Display all log until this UNIX epoch. Conflicts with 'endcursor'.","minimum":0}],"returns":{"items":{"type":"string"},"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/journal\nnodes\njournal\nRead Journal\nnode string The cluster node name.\nendcursor string End before the given Cursor. Conflicts with 'until'\nlastentries integer Limit to the last X lines. Conflicts with a range.\nsince integer Display all log since this UNIX epoch. Conflicts with 'startcursor'.\nstartcursor string Start after the given Cursor. Conflicts with 'since'\nuntil integer Display all log until this UNIX epoch. Conflicts with 'endcursor'."} +{"id":"GET /nodes/{node}/lxc","method":"GET","path":"/nodes/{node}/lxc","section":"nodes","summary":"vmlist","description":"LXC container index (per node).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"description":"Only list CTs where you have VM.Audit permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc\nnodes\nvmlist\nLXC container index (per node).\nnode string The cluster node name.\ncontainer\nct"} +{"id":"POST /nodes/{node}/lxc","method":"POST","path":"/nodes/{node}/lxc","section":"nodes","summary":"create_vm","description":"Create or restore a container.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"ostemplate","type":"string","required":true,"description":"The OS template or backup file."},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"arch","type":"string","required":false,"description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"default":"amd64"},{"name":"bwlimit","type":"number","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"restore limit from datacenter or storage config"},{"name":"cmode","type":"string","required":false,"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"],"default":"tty"},{"name":"console","type":"boolean","required":false,"description":"Attach a console device (/dev/console) to the container.","default":1},{"name":"cores","type":"integer","required":false,"description":"The number of cores assigned to the container. A container can use all available cores by default.","minimum":1,"maximum":8192},{"name":"cpulimit","type":"number","required":false,"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.","default":0,"minimum":0,"maximum":8192},{"name":"cpuunits","type":"integer","required":false,"description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","default":"cgroup v1: 1024, cgroup v2: 100","minimum":0,"maximum":500000},{"name":"debug","type":"boolean","required":false,"description":"Try to be more verbose. For now this only enables debug log-level on start.","default":0},{"name":"description","type":"string","required":false,"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file."},{"name":"dev[n]","type":"string","required":false,"description":"Device to pass through to the container"},{"name":"entrypoint","type":"string","required":false,"description":"Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.","default":"/sbin/init"},{"name":"env","type":"string","required":false,"description":"The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config."},{"name":"features","type":"string","required":false,"description":"Allow containers access to advanced features."},{"name":"force","type":"boolean","required":false,"description":"Allow to overwrite existing container."},{"name":"ha-managed","type":"boolean","required":false,"description":"Add the CT as a HA resource after it was created.","default":0},{"name":"hookscript","type":"string","required":false,"description":"Script that will be executed during various steps in the containers lifetime.","format":"pve-volume-id"},{"name":"hostname","type":"string","required":false,"description":"Set a host name for the container.","format":"dns-name"},{"name":"ignore-unpack-errors","type":"boolean","required":false,"description":"Ignore errors when extracting the template."},{"name":"lock","type":"string","required":false,"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"]},{"name":"memory","type":"integer","required":false,"description":"Amount of RAM for the container in MB.","default":512,"minimum":16},{"name":"mp[n]","type":"string","required":false,"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume."},{"name":"nameserver","type":"string","required":false,"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"},{"name":"net[n]","type":"string","required":false,"description":"Specifies network interfaces for the container."},{"name":"onboot","type":"boolean","required":false,"description":"Specifies whether a container will be started during system bootup.","default":0},{"name":"ostype","type":"string","required":false,"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"]},{"name":"password","type":"string","required":false,"description":"Sets root password inside container."},{"name":"pool","type":"string","required":false,"description":"Add the VM to the specified pool.","format":"pve-poolid"},{"name":"protection","type":"boolean","required":false,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","default":0},{"name":"restore","type":"boolean","required":false,"description":"Mark this as restore task."},{"name":"rootfs","type":"string","required":false,"description":"Use volume as container root."},{"name":"searchdomain","type":"string","required":false,"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"},{"name":"ssh-public-keys","type":"string","required":false,"description":"Setup public SSH keys (one key per line, OpenSSH format)."},{"name":"start","type":"boolean","required":false,"description":"Start the CT after its creation finished successfully.","default":0},{"name":"startup","type":"string","required":false,"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"},{"name":"storage","type":"string","required":false,"description":"Default Storage.","default":"local","format":"pve-storage-id"},{"name":"swap","type":"integer","required":false,"description":"Amount of SWAP for the container in MB.","default":512,"minimum":0},{"name":"tags","type":"string","required":false,"description":"Tags of the Container. This is only meta information.","format":"pve-tag-list"},{"name":"template","type":"boolean","required":false,"description":"Enable/disable Template.","default":0},{"name":"timezone","type":"string","required":false,"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"},{"name":"tty","type":"integer","required":false,"description":"Specify the number of tty available to the container","default":2,"minimum":0,"maximum":6},{"name":"unique","type":"boolean","required":false,"description":"Assign a unique random ethernet address."},{"name":"unprivileged","type":"boolean","required":false,"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.)","default":0},{"name":"unused[n]","type":"string","required":false,"description":"Reference to unused volumes. This is used internally, and should not be modified manually."}],"returns":{"type":"string"},"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"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc\nnodes\ncreate_vm\nCreate or restore a container.\nnode string The cluster node name.\nostemplate string The OS template or backup file.\nvmid integer The (unique) ID of the VM.\narch string OS architecture type. amd64 i386 arm64 armhf riscv32 riscv64\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ncmode string 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). shell console tty\nconsole boolean Attach a console device (/dev/console) to the container.\ncores integer The number of cores assigned to the container. A container can use all available cores by default.\ncpulimit number 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.\ncpuunits integer CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.\ndebug boolean Try to be more verbose. For now this only enables debug log-level on start.\ndescription string Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.\ndev[n] string Device to pass through to the container\nentrypoint string Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.\nenv string The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.\nfeatures string Allow containers access to advanced features.\nforce boolean Allow to overwrite existing container.\nha-managed boolean Add the CT as a HA resource after it was created.\nhookscript string Script that will be executed during various steps in the containers lifetime.\nhostname string Set a host name for the container.\nignore-unpack-errors boolean Ignore errors when extracting the template.\nlock string Lock/unlock the container. backup create destroyed disk fstrim migrate mounted rollback snapshot snapshot-delete\nmemory integer Amount of RAM for the container in MB.\nmp[n] string Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.\nnameserver string Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nnet[n] string Specifies network interfaces for the container.\nonboot boolean Specifies whether a container will be started during system bootup.\nostype string 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. debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo nixos unmanaged\npassword string Sets root password inside container.\npool string Add the VM to the specified pool.\nprotection boolean Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.\nrestore boolean Mark this as restore task.\nrootfs string Use volume as container root.\nsearchdomain string Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nssh-public-keys string Setup public SSH keys (one key per line, OpenSSH format).\nstart boolean Start the CT after its creation finished successfully.\nstartup string 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.\nstorage string Default Storage.\nswap integer Amount of SWAP for the container in MB.\ntags string Tags of the Container. This is only meta information.\ntemplate boolean Enable/disable Template.\ntimezone string 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\ntty integer Specify the number of tty available to the container\nunique boolean Assign a unique random ethernet address.\nunprivileged boolean 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.)\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\ncontainer\nct"} +{"id":"DELETE /nodes/{node}/lxc/{vmid}","method":"DELETE","path":"/nodes/{node}/lxc/{vmid}","section":"nodes","summary":"destroy_vm","description":"Destroy the container (also delete all uses files).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"destroy-unreferenced-disks","type":"boolean","required":false,"description":"If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config."},{"name":"force","type":"boolean","required":false,"description":"Force destroy, even if running.","default":0},{"name":"purge","type":"boolean","required":false,"description":"Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/lxc/{vmid}\nnodes\ndestroy_vm\nDestroy the container (also delete all uses files).\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndestroy-unreferenced-disks boolean If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.\nforce boolean Force destroy, even if running.\npurge boolean Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}","method":"GET","path":"/nodes/{node}/lxc/{vmid}","section":"nodes","summary":"vmdiridx","description":"Directory index","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}\nnodes\nvmdiridx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/clone","method":"POST","path":"/nodes/{node}/lxc/{vmid}/clone","section":"nodes","summary":"clone_vm","description":"Create a container clone/copy","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"newid","type":"integer","required":true,"description":"VMID for the clone.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"bwlimit","type":"number","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"clone limit from datacenter or storage config"},{"name":"description","type":"string","required":false,"description":"Description for the new CT."},{"name":"full","type":"boolean","required":false,"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."},{"name":"hostname","type":"string","required":false,"description":"Set a hostname for the new CT.","format":"dns-name"},{"name":"pool","type":"string","required":false,"description":"Add the new CT to the specified pool.","format":"pve-poolid"},{"name":"snapname","type":"string","required":false,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"storage","type":"string","required":false,"description":"Target storage for full clone.","format":"pve-storage-id"},{"name":"target","type":"string","required":false,"description":"Target node. Only allowed if the original VM is on shared storage.","format":"pve-node"}],"returns":{"type":"string"},"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."},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/clone\nnodes\nclone_vm\nCreate a container clone/copy\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnewid integer VMID for the clone.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndescription string Description for the new CT.\nfull boolean 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.\nhostname string Set a hostname for the new CT.\npool string Add the new CT to the specified pool.\nsnapname string The name of the snapshot.\nstorage string Target storage for full clone.\ntarget string Target node. Only allowed if the original VM is on shared storage.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template"} +{"id":"GET /nodes/{node}/lxc/{vmid}/config","method":"GET","path":"/nodes/{node}/lxc/{vmid}/config","section":"nodes","summary":"vm_config","description":"Get container configuration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"current","type":"boolean","required":false,"description":"Get current values (instead of pending values).","default":0},{"name":"snapshot","type":"string","required":false,"description":"Fetch config values from given snapshot.","format":"pve-configid"}],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/config\nnodes\nvm_config\nGet container configuration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncurrent boolean Get current values (instead of pending values).\nsnapshot string Fetch config values from given snapshot.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/lxc/{vmid}/config","method":"PUT","path":"/nodes/{node}/lxc/{vmid}/config","section":"nodes","summary":"update_vm","description":"Set container options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"arch","type":"string","required":false,"description":"OS architecture type.","enum":["amd64","i386","arm64","armhf","riscv32","riscv64"],"default":"amd64"},{"name":"cmode","type":"string","required":false,"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"],"default":"tty"},{"name":"console","type":"boolean","required":false,"description":"Attach a console device (/dev/console) to the container.","default":1},{"name":"cores","type":"integer","required":false,"description":"The number of cores assigned to the container. A container can use all available cores by default.","minimum":1,"maximum":8192},{"name":"cpulimit","type":"number","required":false,"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.","default":0,"minimum":0,"maximum":8192},{"name":"cpuunits","type":"integer","required":false,"description":"CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.","default":"cgroup v1: 1024, cgroup v2: 100","minimum":0,"maximum":500000},{"name":"debug","type":"boolean","required":false,"description":"Try to be more verbose. For now this only enables debug log-level on start.","default":0},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file."},{"name":"dev[n]","type":"string","required":false,"description":"Device to pass through to the container"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications."},{"name":"entrypoint","type":"string","required":false,"description":"Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.","default":"/sbin/init"},{"name":"env","type":"string","required":false,"description":"The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config."},{"name":"features","type":"string","required":false,"description":"Allow containers access to advanced features."},{"name":"hookscript","type":"string","required":false,"description":"Script that will be executed during various steps in the containers lifetime.","format":"pve-volume-id"},{"name":"hostname","type":"string","required":false,"description":"Set a host name for the container.","format":"dns-name"},{"name":"lock","type":"string","required":false,"description":"Lock/unlock the container.","enum":["backup","create","destroyed","disk","fstrim","migrate","mounted","rollback","snapshot","snapshot-delete"]},{"name":"memory","type":"integer","required":false,"description":"Amount of RAM for the container in MB.","default":512,"minimum":16},{"name":"mp[n]","type":"string","required":false,"description":"Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume."},{"name":"nameserver","type":"string","required":false,"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"},{"name":"net[n]","type":"string","required":false,"description":"Specifies network interfaces for the container."},{"name":"onboot","type":"boolean","required":false,"description":"Specifies whether a container will be started during system bootup.","default":0},{"name":"ostype","type":"string","required":false,"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"]},{"name":"protection","type":"boolean","required":false,"description":"Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.","default":0},{"name":"revert","type":"string","required":false,"description":"Revert a pending change.","format":"pve-configid-list"},{"name":"rootfs","type":"string","required":false,"description":"Use volume as container root."},{"name":"searchdomain","type":"string","required":false,"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"},{"name":"startup","type":"string","required":false,"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"},{"name":"swap","type":"integer","required":false,"description":"Amount of SWAP for the container in MB.","default":512,"minimum":0},{"name":"tags","type":"string","required":false,"description":"Tags of the Container. This is only meta information.","format":"pve-tag-list"},{"name":"template","type":"boolean","required":false,"description":"Enable/disable Template.","default":0},{"name":"timezone","type":"string","required":false,"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"},{"name":"tty","type":"integer","required":false,"description":"Specify the number of tty available to the container","default":2,"minimum":0,"maximum":6},{"name":"unprivileged","type":"boolean","required":false,"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.)","default":0},{"name":"unused[n]","type":"string","required":false,"description":"Reference to unused volumes. This is used internally, and should not be modified manually."}],"returns":{"type":"null"},"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"},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/lxc/{vmid}/config\nnodes\nupdate_vm\nSet container options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\narch string OS architecture type. amd64 i386 arm64 armhf riscv32 riscv64\ncmode string 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). shell console tty\nconsole boolean Attach a console device (/dev/console) to the container.\ncores integer The number of cores assigned to the container. A container can use all available cores by default.\ncpulimit number 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.\ncpuunits integer CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.\ndebug boolean Try to be more verbose. For now this only enables debug log-level on start.\ndelete string A list of settings you want to delete.\ndescription string Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.\ndev[n] string Device to pass through to the container\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nentrypoint string Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.\nenv string The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.\nfeatures string Allow containers access to advanced features.\nhookscript string Script that will be executed during various steps in the containers lifetime.\nhostname string Set a host name for the container.\nlock string Lock/unlock the container. backup create destroyed disk fstrim migrate mounted rollback snapshot snapshot-delete\nmemory integer Amount of RAM for the container in MB.\nmp[n] string Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.\nnameserver string Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nnet[n] string Specifies network interfaces for the container.\nonboot boolean Specifies whether a container will be started during system bootup.\nostype string 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. debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo nixos unmanaged\nprotection boolean Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.\nrevert string Revert a pending change.\nrootfs string Use volume as container root.\nsearchdomain string Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nstartup string 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.\nswap integer Amount of SWAP for the container in MB.\ntags string Tags of the Container. This is only meta information.\ntemplate boolean Enable/disable Template.\ntimezone string 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\ntty integer Specify the number of tty available to the container\nunprivileged boolean 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.)\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/feature","method":"GET","path":"/nodes/{node}/lxc/{vmid}/feature","section":"nodes","summary":"vm_feature","description":"Check if feature for virtual machine is available.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"feature","type":"string","required":true,"description":"Feature to check.","enum":["snapshot","clone","copy"]},{"name":"snapname","type":"string","required":false,"description":"The name of the snapshot.","format":"pve-configid"}],"returns":{"properties":{"hasFeature":{"type":"boolean"}},"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/feature\nnodes\nvm_feature\nCheck if feature for virtual machine is available.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfeature string Feature to check. snapshot clone copy\nsnapname string The name of the snapshot.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall","section":"nodes","summary":"index","description":"Directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/aliases","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/aliases","section":"nodes","summary":"get_aliases","description":"List aliases","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/aliases\nnodes\nget_aliases\nList aliases\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/firewall/aliases","method":"POST","path":"/nodes/{node}/lxc/{vmid}/firewall/aliases","section":"nodes","summary":"create_alias","description":"Create IP or Network Alias.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDR"},{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"comment","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/firewall/aliases\nnodes\ncreate_alias\nCreate IP or Network Alias.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}","method":"DELETE","path":"/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}","section":"nodes","summary":"remove_alias","description":"Remove IP or Network alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}","section":"nodes","summary":"read_alias","description":"Read alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nread_alias\nRead alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}","method":"PUT","path":"/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}","section":"nodes","summary":"update_alias","description":"Update IP or Network alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDR"},{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"rename","type":"string","required":false,"description":"Rename an existing alias."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/ipset","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset","section":"nodes","summary":"ipset_index","description":"List IPSets","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset\nnodes\nipset_index\nList IPSets\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/firewall/ipset","method":"POST","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset","section":"nodes","summary":"create_ipset","description":"Create new IPSet","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"rename","type":"string","required":false,"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/firewall/ipset\nnodes\ncreate_ipset\nCreate new IPSet\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}","method":"DELETE","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}","section":"nodes","summary":"delete_ipset","description":"Delete IPSet","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Delete all members of the IPSet, if there are any."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\ndelete_ipset\nDelete IPSet\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce boolean Delete all members of the IPSet, if there are any.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}","section":"nodes","summary":"get_ipset","description":"List IPSet content","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\nget_ipset\nList IPSet content\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}","method":"POST","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}","section":"nodes","summary":"create_ip","description":"Add IP or Network to IPSet.","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"comment","type":"string","required":false},{"name":"nomatch","type":"boolean","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}","method":"DELETE","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}","section":"nodes","summary":"remove_ip","description":"Remove IP or Network from IPSet.","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}","section":"nodes","summary":"read_ip","description":"Read IP or Network settings from IPSet.","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}","method":"PUT","path":"/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}","section":"nodes","summary":"update_ip","description":"Update IP or Network settings","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"nomatch","type":"boolean","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/log","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/log","section":"nodes","summary":"log","description":"Read firewall log","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"limit","type":"integer","required":false,"minimum":0},{"name":"since","type":"integer","required":false,"description":"Display log since this UNIX epoch.","minimum":0},{"name":"start","type":"integer","required":false,"minimum":0},{"name":"until","type":"integer","required":false,"description":"Display log until this UNIX epoch.","minimum":0}],"returns":{"items":{"properties":{"n":{"description":"Line number","type":"integer"},"t":{"description":"Line text","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/options","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/options","section":"nodes","summary":"get_options","description":"Get VM firewall options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/options\nnodes\nget_options\nGet VM firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/lxc/{vmid}/firewall/options","method":"PUT","path":"/nodes/{node}/lxc/{vmid}/firewall/options","section":"nodes","summary":"set_options","description":"Set Firewall options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dhcp","type":"boolean","required":false,"description":"Enable DHCP.","default":0},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"enable","type":"boolean","required":false,"description":"Enable/disable firewall rules.","default":0},{"name":"ipfilter","type":"boolean","required":false,"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."},{"name":"log_level_in","type":"string","required":false,"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"log_level_out","type":"string","required":false,"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macfilter","type":"boolean","required":false,"description":"Enable/disable MAC address filter.","default":1},{"name":"ndp","type":"boolean","required":false,"description":"Enable NDP (Neighbor Discovery Protocol).","default":1},{"name":"policy_in","type":"string","required":false,"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"]},{"name":"policy_out","type":"string","required":false,"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"]},{"name":"radv","type":"boolean","required":false,"description":"Allow sending Router Advertisement."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/lxc/{vmid}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndelete string A list of settings you want to delete.\ndhcp boolean Enable DHCP.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nipfilter boolean 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.\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nmacfilter boolean Enable/disable MAC address filter.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP\nradv boolean Allow sending Router Advertisement.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/refs","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/refs","section":"nodes","summary":"refs","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list references of specified type.","enum":["alias","ipset"]}],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/refs\nnodes\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Only list references of specified type. alias ipset\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/rules","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/rules","section":"nodes","summary":"get_rules","description":"List rules.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/firewall/rules","method":"POST","path":"/nodes/{node}/lxc/{vmid}/firewall/rules","section":"nodes","summary":"create_rule","description":"Create new rule.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"type","type":"string","required":true,"description":"Rule type.","enum":["in","out","forward","group"]},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}","method":"DELETE","path":"/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}","section":"nodes","summary":"delete_rule","description":"Delete rule.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}","method":"GET","path":"/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}","section":"nodes","summary":"get_rule","description":"Get single rule data.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}","method":"PUT","path":"/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}","section":"nodes","summary":"update_rule","description":"Modify rule data.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"action","type":"string","required":false,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"moveto","type":"integer","required":false,"description":"Move rule to new position . Other arguments are ignored.","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"},{"name":"type","type":"string","required":false,"description":"Rule type.","enum":["in","out","forward","group"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/interfaces","method":"GET","path":"/nodes/{node}/lxc/{vmid}/interfaces","section":"nodes","summary":"ip","description":"Get IP addresses of the specified container interface.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/interfaces\nnodes\nip\nGet IP addresses of the specified container interface.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/migrate","method":"GET","path":"/nodes/{node}/lxc/{vmid}/migrate","section":"nodes","summary":"migrate_vm_precondition","description":"Get preconditions for migration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"target","type":"string","required":false,"description":"Target node.","format":"pve-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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/migrate\nnodes\nmigrate_vm_precondition\nGet preconditions for migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/migrate","method":"POST","path":"/nodes/{node}/lxc/{vmid}/migrate","section":"nodes","summary":"migrate_vm","description":"Migrate the container to another node. Creates a new migration task.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"target","type":"string","required":true,"description":"Target node.","format":"pve-node"},{"name":"bwlimit","type":"number","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"migrate limit from datacenter or storage config"},{"name":"online","type":"boolean","required":false,"description":"Use online/live migration."},{"name":"restart","type":"boolean","required":false,"description":"Use restart migration"},{"name":"target-storage","type":"string","required":false,"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"},{"name":"timeout","type":"integer","required":false,"description":"Timeout in seconds for shutdown for restart migration","default":180}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/migrate\nnodes\nmigrate_vm\nMigrate the container to another node. Creates a new migration task.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\nonline boolean Use online/live migration.\nrestart boolean Use restart migration\ntarget-storage string 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.\ntimeout integer Timeout in seconds for shutdown for restart migration\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/move_volume","method":"POST","path":"/nodes/{node}/lxc/{vmid}/move_volume","section":"nodes","summary":"move_volume","description":"Move a rootfs-/mp-volume to a different storage or to a different container.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"volume","type":"string","required":true,"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"]},{"name":"bwlimit","type":"number","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"clone limit from datacenter or storage config"},{"name":"delete","type":"boolean","required":false,"description":"Delete the original volume after successful copy. By default the original is kept as an unused volume entry.","default":0},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications."},{"name":"storage","type":"string","required":false,"description":"Target Storage.","format":"pve-storage-id"},{"name":"target-digest","type":"string","required":false,"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."},{"name":"target-vmid","type":"integer","required":false,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"target-volume","type":"string","required":false,"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"]}],"returns":{"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."},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/move_volume\nnodes\nmove_volume\nMove a rootfs-/mp-volume to a different storage or to a different container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvolume string Volume which will be moved. 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\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndelete boolean Delete the original volume after successful copy. By default the original is kept as an unused volume entry.\ndigest string Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.\nstorage string Target Storage.\ntarget-digest string 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.\ntarget-vmid integer The (unique) ID of the VM.\ntarget-volume string The config key the volume will be moved to. Default is the source volume key. 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\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/mtunnel","method":"POST","path":"/nodes/{node}/lxc/{vmid}/mtunnel","section":"nodes","summary":"mtunnel","description":"Migration tunnel endpoint - only for internal use by CT migration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"bridges","type":"string","required":false,"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","format":"pve-bridge-id-list"},{"name":"storages","type":"string","required":false,"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"}],"returns":{"additionalProperties":0,"properties":{"socket":{"type":"string"},"ticket":{"type":"string"},"upid":{"type":"string"}}},"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."},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/mtunnel\nnodes\nmtunnel\nMigration tunnel endpoint - only for internal use by CT migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nbridges string List of network bridges to check availability. Will be checked again for actually used bridges during migration.\nstorages string List of storages to check permission and availability. Will be checked again for all actually used storages during migration.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/mtunnelwebsocket","method":"GET","path":"/nodes/{node}/lxc/{vmid}/mtunnelwebsocket","section":"nodes","summary":"mtunnelwebsocket","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"socket","type":"string","required":true,"description":"unix socket to forward to"},{"name":"ticket","type":"string","required":true,"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command"}],"returns":{"properties":{"port":{"optional":1,"type":"string"},"socket":{"optional":1,"type":"string"}},"type":"object"},"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"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/mtunnelwebsocket\nnodes\nmtunnelwebsocket\nMigration tunnel endpoint for websocket upgrade - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsocket string unix socket to forward to\nticket string ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/pending","method":"GET","path":"/nodes/{node}/lxc/{vmid}/pending","section":"nodes","summary":"vm_pending","description":"Get container configuration, including pending changes.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/pending\nnodes\nvm_pending\nGet container configuration, including pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/remote_migrate","method":"POST","path":"/nodes/{node}/lxc/{vmid}/remote_migrate","section":"nodes","summary":"remote_migrate_vm","description":"Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"target-bridge","type":"string","required":true,"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"},{"name":"target-endpoint","type":"string","required":true,"description":"Remote target endpoint","format":"proxmox-remote"},{"name":"target-storage","type":"string","required":true,"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"},{"name":"bwlimit","type":"number","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"migrate limit from datacenter or storage config"},{"name":"delete","type":"boolean","required":false,"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.","default":0},{"name":"online","type":"boolean","required":false,"description":"Use online/live migration."},{"name":"restart","type":"boolean","required":false,"description":"Use restart migration"},{"name":"target-vmid","type":"integer","required":false,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"timeout","type":"integer","required":false,"description":"Timeout in seconds for shutdown for restart migration","default":180}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/remote_migrate\nnodes\nremote_migrate_vm\nMigrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget-bridge string 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.\ntarget-endpoint string Remote target endpoint\ntarget-storage string 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.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndelete boolean 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.\nonline boolean Use online/live migration.\nrestart boolean Use restart migration\ntarget-vmid integer The (unique) ID of the VM.\ntimeout integer Timeout in seconds for shutdown for restart migration\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/lxc/{vmid}/resize","method":"PUT","path":"/nodes/{node}/lxc/{vmid}/resize","section":"nodes","summary":"resize_vm","description":"Resize a container mount point.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"disk","type":"string","required":true,"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"]},{"name":"size","type":"string","required":true,"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."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications."}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"],"any",1]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/lxc/{vmid}/resize\nnodes\nresize_vm\nResize a container mount point.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to resize. 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\nsize string 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.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/rrd","method":"GET","path":"/nodes/{node}/lxc/{vmid}/rrd","section":"nodes","summary":"rrd","description":"Read VM RRD statistics (returns PNG)","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"ds","type":"string","required":true,"description":"The list of datasources you want to display.","format":"pve-configid-list"},{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"properties":{"filename":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/rrd\nnodes\nrrd\nRead VM RRD statistics (returns PNG)\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/rrddata","method":"GET","path":"/nodes/{node}/lxc/{vmid}/rrddata","section":"nodes","summary":"rrddata","description":"Read VM RRD statistics","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/rrddata\nnodes\nrrddata\nRead VM RRD statistics\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/snapshot","method":"GET","path":"/nodes/{node}/lxc/{vmid}/snapshot","section":"nodes","summary":"list","description":"List all snapshots.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/snapshot\nnodes\nlist\nList all snapshots.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"POST /nodes/{node}/lxc/{vmid}/snapshot","method":"POST","path":"/nodes/{node}/lxc/{vmid}/snapshot","section":"nodes","summary":"snapshot","description":"Snapshot a container.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"description","type":"string","required":false,"description":"A textual description or comment."}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/snapshot\nnodes\nsnapshot\nSnapshot a container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsnapname string The name of the snapshot.\ndescription string A textual description or comment.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"DELETE /nodes/{node}/lxc/{vmid}/snapshot/{snapname}","method":"DELETE","path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}","section":"nodes","summary":"delsnapshot","description":"Delete a LXC snapshot.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"For removal from config file, even if removing disk snapshots fails."}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}\nnodes\ndelsnapshot\nDelete a LXC snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nforce boolean For removal from config file, even if removing disk snapshots fails.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}","method":"GET","path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}","section":"nodes","summary":"snapshot_cmd_idx","description":"snapshot_cmd_idx","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{cmd}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}\nnodes\nsnapshot_cmd_idx\nsnapshot_cmd_idx\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config","method":"GET","path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config","section":"nodes","summary":"get_snapshot_config","description":"Get snapshot configuration","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config\nnodes\nget_snapshot_config\nGet snapshot configuration\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"PUT /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config","method":"PUT","path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config","section":"nodes","summary":"update_snapshot_config","description":"Update snapshot metadata.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"description","type":"string","required":false,"description":"A textual description or comment."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config\nnodes\nupdate_snapshot_config\nUpdate snapshot metadata.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ndescription string A textual description or comment.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"POST /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback","method":"POST","path":"/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback","section":"nodes","summary":"rollback","description":"Rollback LXC state to specified snapshot.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"start","type":"boolean","required":false,"description":"Whether the container should get started after rolling back successfully","default":0}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback\nnodes\nrollback\nRollback LXC state to specified snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nstart boolean Whether the container should get started after rolling back successfully\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"POST /nodes/{node}/lxc/{vmid}/spiceproxy","method":"POST","path":"/nodes/{node}/lxc/{vmid}/spiceproxy","section":"nodes","summary":"spiceproxy","description":"Returns a SPICE configuration to connect to the CT.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"proxy","type":"string","required":false,"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"}],"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"}}},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/spiceproxy\nnodes\nspiceproxy\nReturns a SPICE configuration to connect to the CT.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nproxy string 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).\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/status","method":"GET","path":"/nodes/{node}/lxc/{vmid}/status","section":"nodes","summary":"vmcmdidx","description":"Directory index","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/status\nnodes\nvmcmdidx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/status/current","method":"GET","path":"/nodes/{node}/lxc/{vmid}/status/current","section":"nodes","summary":"vm_status","description":"Get virtual machine status.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/status/current\nnodes\nvm_status\nGet virtual machine status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/status/reboot","method":"POST","path":"/nodes/{node}/lxc/{vmid}/status/reboot","section":"nodes","summary":"vm_reboot","description":"Reboot the container by shutting it down, and starting it again. Applies pending changes.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"timeout","type":"integer","required":false,"description":"Wait maximal timeout seconds for the shutdown.","minimum":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/status/reboot\nnodes\nvm_reboot\nReboot the container by shutting it down, and starting it again. Applies pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeout integer Wait maximal timeout seconds for the shutdown.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/status/resume","method":"POST","path":"/nodes/{node}/lxc/{vmid}/status/resume","section":"nodes","summary":"vm_resume","description":"Resume the container.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/status/resume\nnodes\nvm_resume\nResume the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/status/shutdown","method":"POST","path":"/nodes/{node}/lxc/{vmid}/status/shutdown","section":"nodes","summary":"vm_shutdown","description":"Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"forceStop","type":"boolean","required":false,"description":"Make sure the Container stops.","default":0},{"name":"timeout","type":"integer","required":false,"description":"Wait maximal timeout seconds.","default":60,"minimum":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/status/shutdown\nnodes\nvm_shutdown\nShutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforceStop boolean Make sure the Container stops.\ntimeout integer Wait maximal timeout seconds.\ncontainer\nct\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop"} +{"id":"POST /nodes/{node}/lxc/{vmid}/status/start","method":"POST","path":"/nodes/{node}/lxc/{vmid}/status/start","section":"nodes","summary":"vm_start","description":"Start the container.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"debug","type":"boolean","required":false,"description":"If set, enables very verbose debug log-level on start.","default":0},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/status/start\nnodes\nvm_start\nStart the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndebug boolean If set, enables very verbose debug log-level on start.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ncontainer\nct\nguest id\nvm id\ncontainer id\nstart\nboot\npower on"} +{"id":"POST /nodes/{node}/lxc/{vmid}/status/stop","method":"POST","path":"/nodes/{node}/lxc/{vmid}/status/stop","section":"nodes","summary":"vm_stop","description":"Stop the container. This will abruptly stop all processes running in the container.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"overrule-shutdown","type":"boolean","required":false,"description":"Try to abort active 'vzshutdown' tasks before stopping.","default":0},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/status/stop\nnodes\nvm_stop\nStop the container. This will abruptly stop all processes running in the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\noverrule-shutdown boolean Try to abort active 'vzshutdown' tasks before stopping.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ncontainer\nct\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off"} +{"id":"POST /nodes/{node}/lxc/{vmid}/status/suspend","method":"POST","path":"/nodes/{node}/lxc/{vmid}/status/suspend","section":"nodes","summary":"vm_suspend","description":"Suspend the container. This is experimental.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/status/suspend\nnodes\nvm_suspend\nSuspend the container. This is experimental.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/template","method":"POST","path":"/nodes/{node}/lxc/{vmid}/template","section":"nodes","summary":"template","description":"Create a Template.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Allocate"]],"description":"You need 'VM.Allocate' permissions on /vms/{vmid}"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/template\nnodes\ntemplate\nCreate a Template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/termproxy","method":"POST","path":"/nodes/{node}/lxc/{vmid}/termproxy","section":"nodes","summary":"termproxy","description":"Creates a TCP proxy connection.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"additionalProperties":0,"properties":{"port":{"type":"integer"},"ticket":{"type":"string"},"upid":{"type":"string"},"user":{"type":"string"}}},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/termproxy\nnodes\ntermproxy\nCreates a TCP proxy connection.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/lxc/{vmid}/vncproxy","method":"POST","path":"/nodes/{node}/lxc/{vmid}/vncproxy","section":"nodes","summary":"vncproxy","description":"Creates a TCP VNC proxy connections.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"height","type":"integer","required":false,"description":"sets the height of the console in pixels.","minimum":16,"maximum":2160},{"name":"websocket","type":"boolean","required":false,"description":"use websocket instead of standard VNC."},{"name":"width","type":"integer","required":false,"description":"sets the width of the console in pixels.","minimum":16,"maximum":4096}],"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"}}},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/lxc/{vmid}/vncproxy\nnodes\nvncproxy\nCreates a TCP VNC proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nheight integer sets the height of the console in pixels.\nwebsocket boolean use websocket instead of standard VNC.\nwidth integer sets the width of the console in pixels.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/lxc/{vmid}/vncwebsocket","method":"GET","path":"/nodes/{node}/lxc/{vmid}/vncwebsocket","section":"nodes","summary":"vncwebsocket","description":"Opens a websocket for VNC traffic.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"port","type":"integer","required":true,"description":"Port number returned by previous vncproxy call.","minimum":5900,"maximum":5999},{"name":"vncticket","type":"string","required":true,"description":"Ticket from previous call to vncproxy."}],"returns":{"properties":{"port":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]],"description":"You also need to pass a valid ticket (vncticket)."},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/lxc/{vmid}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nport integer Port number returned by previous vncproxy call.\nvncticket string Ticket from previous call to vncproxy.\ncontainer\nct\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/migrateall","method":"POST","path":"/nodes/{node}/migrateall","section":"nodes","summary":"migrateall","description":"Migrate all VMs and Containers.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"target","type":"string","required":true,"description":"Target node.","format":"pve-node"},{"name":"max-workers","type":"integer","required":false,"description":"Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!","minimum":1,"maximum":64},{"name":"maxworkers","type":"integer","required":false,"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.","minimum":1,"maximum":64},{"name":"vms","type":"string","required":false,"description":"Only consider Guests with these IDs.","format":"pve-vmid-list"},{"name":"with-local-disks","type":"boolean","required":false,"description":"Enable live storage migration for local disk"}],"returns":{"type":"string"},"permissions":{"description":"The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","user":"all"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/migrateall\nnodes\nmigrateall\nMigrate all VMs and Containers.\nnode string The cluster node name.\ntarget string Target node.\nmax-workers integer Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!\nmaxworkers integer 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.\nvms string Only consider Guests with these IDs.\nwith-local-disks boolean Enable live storage migration for local disk"} +{"id":"GET /nodes/{node}/netstat","method":"GET","path":"/nodes/{node}/netstat","section":"nodes","summary":"netstat","description":"Read tap/vm network device interface counters","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/netstat\nnodes\nnetstat\nRead tap/vm network device interface counters\nnode string The cluster node name."} +{"id":"DELETE /nodes/{node}/network","method":"DELETE","path":"/nodes/{node}/network","section":"nodes","summary":"revert_network_changes","description":"Revert network configuration changes.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/network\nnodes\nrevert_network_changes\nRevert network configuration changes.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/network","method":"GET","path":"/nodes/{node}/network","section":"nodes","summary":"index","description":"List available networks","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"type","type":"string","required":false,"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"]}],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/network\nnodes\nindex\nList available networks\nnode string The cluster node name.\ntype string Only list specific interface types. bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet any_bridge any_local_bridge include_sdn"} +{"id":"POST /nodes/{node}/network","method":"POST","path":"/nodes/{node}/network","section":"nodes","summary":"create_network","description":"Create network device configuration","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"iface","type":"string","required":true,"description":"Network interface name.","format":"pve-iface"},{"name":"type","type":"string","required":true,"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","fabric","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"]},{"name":"address","type":"string","required":false,"description":"IP address.","format":"ipv4"},{"name":"address6","type":"string","required":false,"description":"IP address.","format":"ipv6"},{"name":"autostart","type":"boolean","required":false,"description":"Automatically start interface on boot."},{"name":"bond_mode","type":"string","required":false,"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"]},{"name":"bond_xmit_hash_policy","type":"string","required":false,"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"]},{"name":"bond-primary","type":"string","required":false,"description":"Specify the primary interface for active-backup bond.","format":"pve-iface"},{"name":"bridge_ports","type":"string","required":false,"description":"Specify the interfaces you want to add to your bridge.","format":"pve-iface-list"},{"name":"bridge_vids","type":"string","required":false,"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"},{"name":"bridge_vlan_aware","type":"boolean","required":false,"description":"Enable bridge vlan support."},{"name":"cidr","type":"string","required":false,"description":"IPv4 CIDR.","format":"CIDRv4"},{"name":"cidr6","type":"string","required":false,"description":"IPv6 CIDR.","format":"CIDRv6"},{"name":"comments","type":"string","required":false,"description":"Comments"},{"name":"comments6","type":"string","required":false,"description":"Comments"},{"name":"gateway","type":"string","required":false,"description":"Default gateway address.","format":"ipv4"},{"name":"gateway6","type":"string","required":false,"description":"Default ipv6 gateway address.","format":"ipv6"},{"name":"mtu","type":"integer","required":false,"description":"MTU.","minimum":1280,"maximum":65520},{"name":"netmask","type":"string","required":false,"description":"Network mask.","format":"ipv4mask"},{"name":"netmask6","type":"integer","required":false,"description":"Network mask.","minimum":0,"maximum":128},{"name":"ovs_bonds","type":"string","required":false,"description":"Specify the interfaces used by the bonding device.","format":"pve-iface-list"},{"name":"ovs_bridge","type":"string","required":false,"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","format":"pve-iface"},{"name":"ovs_options","type":"string","required":false,"description":"OVS interface options."},{"name":"ovs_ports","type":"string","required":false,"description":"Specify the interfaces you want to add to your bridge.","format":"pve-iface-list"},{"name":"ovs_tag","type":"integer","required":false,"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","minimum":1,"maximum":4094},{"name":"slaves","type":"string","required":false,"description":"Specify the interfaces used by the bonding device.","format":"pve-iface-list"},{"name":"vlan-id","type":"integer","required":false,"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","minimum":1,"maximum":4094},{"name":"vlan-raw-device","type":"string","required":false,"description":"Specify the raw interface for the vlan interface.","format":"pve-iface"}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/network\nnodes\ncreate_network\nCreate network device configuration\nnode string The cluster node name.\niface string Network interface name.\ntype string Network interface type bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet unknown\naddress string IP address.\naddress6 string IP address.\nautostart boolean Automatically start interface on boot.\nbond_mode string Bonding mode. balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb balance-slb lacp-balance-slb lacp-balance-tcp\nbond_xmit_hash_policy string Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. layer2 layer2+3 layer3+4\nbond-primary string Specify the primary interface for active-backup bond.\nbridge_ports string Specify the interfaces you want to add to your bridge.\nbridge_vids string Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.\nbridge_vlan_aware boolean Enable bridge vlan support.\ncidr string IPv4 CIDR.\ncidr6 string IPv6 CIDR.\ncomments string Comments\ncomments6 string Comments\ngateway string Default gateway address.\ngateway6 string Default ipv6 gateway address.\nmtu integer MTU.\nnetmask string Network mask.\nnetmask6 integer Network mask.\novs_bonds string Specify the interfaces used by the bonding device.\novs_bridge string The OVS bridge associated with a OVS port. This is required when you create an OVS port.\novs_options string OVS interface options.\novs_ports string Specify the interfaces you want to add to your bridge.\novs_tag integer Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)\nslaves string Specify the interfaces used by the bonding device.\nvlan-id integer vlan-id for a custom named vlan interface (ifupdown2 only).\nvlan-raw-device string Specify the raw interface for the vlan interface."} +{"id":"PUT /nodes/{node}/network","method":"PUT","path":"/nodes/{node}/network","section":"nodes","summary":"reload_network_config","description":"Reload network configuration","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"regenerate-frr","type":"boolean","required":false,"description":"Whether FRR config generation should get skipped or not.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/network\nnodes\nreload_network_config\nReload network configuration\nnode string The cluster node name.\nregenerate-frr boolean Whether FRR config generation should get skipped or not."} +{"id":"DELETE /nodes/{node}/network/{iface}","method":"DELETE","path":"/nodes/{node}/network/{iface}","section":"nodes","summary":"delete_network","description":"Delete network device configuration","pathParameters":[{"name":"iface","type":"string","required":true,"description":"Network interface name.","format":"pve-iface"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/network/{iface}\nnodes\ndelete_network\nDelete network device configuration\niface string Network interface name.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/network/{iface}","method":"GET","path":"/nodes/{node}/network/{iface}","section":"nodes","summary":"network_config","description":"Read network device configuration","pathParameters":[{"name":"iface","type":"string","required":true,"description":"Network interface name.","format":"pve-iface"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"properties":{"method":{"type":"string"},"type":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/network/{iface}\nnodes\nnetwork_config\nRead network device configuration\niface string Network interface name.\nnode string The cluster node name."} +{"id":"PUT /nodes/{node}/network/{iface}","method":"PUT","path":"/nodes/{node}/network/{iface}","section":"nodes","summary":"update_network","description":"Update network device configuration","pathParameters":[{"name":"iface","type":"string","required":true,"description":"Network interface name.","format":"pve-iface"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"type","type":"string","required":true,"description":"Network interface type","enum":["bridge","bond","eth","alias","vlan","fabric","OVSBridge","OVSBond","OVSPort","OVSIntPort","vnet","unknown"]},{"name":"address","type":"string","required":false,"description":"IP address.","format":"ipv4"},{"name":"address6","type":"string","required":false,"description":"IP address.","format":"ipv6"},{"name":"autostart","type":"boolean","required":false,"description":"Automatically start interface on boot."},{"name":"bond_mode","type":"string","required":false,"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"]},{"name":"bond_xmit_hash_policy","type":"string","required":false,"description":"Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes.","enum":["layer2","layer2+3","layer3+4"]},{"name":"bond-primary","type":"string","required":false,"description":"Specify the primary interface for active-backup bond.","format":"pve-iface"},{"name":"bridge_ports","type":"string","required":false,"description":"Specify the interfaces you want to add to your bridge.","format":"pve-iface-list"},{"name":"bridge_vids","type":"string","required":false,"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"},{"name":"bridge_vlan_aware","type":"boolean","required":false,"description":"Enable bridge vlan support."},{"name":"cidr","type":"string","required":false,"description":"IPv4 CIDR.","format":"CIDRv4"},{"name":"cidr6","type":"string","required":false,"description":"IPv6 CIDR.","format":"CIDRv6"},{"name":"comments","type":"string","required":false,"description":"Comments"},{"name":"comments6","type":"string","required":false,"description":"Comments"},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"gateway","type":"string","required":false,"description":"Default gateway address.","format":"ipv4"},{"name":"gateway6","type":"string","required":false,"description":"Default ipv6 gateway address.","format":"ipv6"},{"name":"mtu","type":"integer","required":false,"description":"MTU.","minimum":1280,"maximum":65520},{"name":"netmask","type":"string","required":false,"description":"Network mask.","format":"ipv4mask"},{"name":"netmask6","type":"integer","required":false,"description":"Network mask.","minimum":0,"maximum":128},{"name":"ovs_bonds","type":"string","required":false,"description":"Specify the interfaces used by the bonding device.","format":"pve-iface-list"},{"name":"ovs_bridge","type":"string","required":false,"description":"The OVS bridge associated with a OVS port. This is required when you create an OVS port.","format":"pve-iface"},{"name":"ovs_options","type":"string","required":false,"description":"OVS interface options."},{"name":"ovs_ports","type":"string","required":false,"description":"Specify the interfaces you want to add to your bridge.","format":"pve-iface-list"},{"name":"ovs_tag","type":"integer","required":false,"description":"Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)","minimum":1,"maximum":4094},{"name":"slaves","type":"string","required":false,"description":"Specify the interfaces used by the bonding device.","format":"pve-iface-list"},{"name":"vlan-id","type":"integer","required":false,"description":"vlan-id for a custom named vlan interface (ifupdown2 only).","minimum":1,"maximum":4094},{"name":"vlan-raw-device","type":"string","required":false,"description":"Specify the raw interface for the vlan interface.","format":"pve-iface"}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/network/{iface}\nnodes\nupdate_network\nUpdate network device configuration\niface string Network interface name.\nnode string The cluster node name.\ntype string Network interface type bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet unknown\naddress string IP address.\naddress6 string IP address.\nautostart boolean Automatically start interface on boot.\nbond_mode string Bonding mode. balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb balance-slb lacp-balance-slb lacp-balance-tcp\nbond_xmit_hash_policy string Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. layer2 layer2+3 layer3+4\nbond-primary string Specify the primary interface for active-backup bond.\nbridge_ports string Specify the interfaces you want to add to your bridge.\nbridge_vids string Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.\nbridge_vlan_aware boolean Enable bridge vlan support.\ncidr string IPv4 CIDR.\ncidr6 string IPv6 CIDR.\ncomments string Comments\ncomments6 string Comments\ndelete string A list of settings you want to delete.\ngateway string Default gateway address.\ngateway6 string Default ipv6 gateway address.\nmtu integer MTU.\nnetmask string Network mask.\nnetmask6 integer Network mask.\novs_bonds string Specify the interfaces used by the bonding device.\novs_bridge string The OVS bridge associated with a OVS port. This is required when you create an OVS port.\novs_options string OVS interface options.\novs_ports string Specify the interfaces you want to add to your bridge.\novs_tag integer Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)\nslaves string Specify the interfaces used by the bonding device.\nvlan-id integer vlan-id for a custom named vlan interface (ifupdown2 only).\nvlan-raw-device string Specify the raw interface for the vlan interface."} +{"id":"GET /nodes/{node}/qemu","method":"GET","path":"/nodes/{node}/qemu","section":"nodes","summary":"vmlist","description":"Virtual machine index (per node).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"full","type":"boolean","required":false,"description":"Determine the full status of active VMs."}],"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"},"permissions":{"description":"Only list VMs where you have VM.Audit permissions on /vms/.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu\nnodes\nvmlist\nVirtual machine index (per node).\nnode string The cluster node name.\nfull boolean Determine the full status of active VMs.\nvm\nvirtual machine\nkvm guest"} +{"id":"POST /nodes/{node}/qemu","method":"POST","path":"/nodes/{node}/qemu","section":"nodes","summary":"create_vm","description":"Create or restore a virtual machine.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"acpi","type":"boolean","required":false,"description":"Enable/disable ACPI.","default":1},{"name":"affinity","type":"string","required":false,"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","format":"pve-cpuset"},{"name":"agent","type":"string","required":false,"description":"Enable/disable communication with the QEMU Guest Agent and its properties."},{"name":"allow-ksm","type":"boolean","required":false,"description":"Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).","default":1},{"name":"amd-sev","type":"string","required":false,"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","format":"pve-qemu-sev-fmt"},{"name":"arch","type":"string","required":false,"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"]},{"name":"archive","type":"string","required":false,"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."},{"name":"args","type":"string","required":false,"description":"Arbitrary arguments passed to kvm."},{"name":"audio0","type":"string","required":false,"description":"Configure a audio device, useful in combination with QXL/Spice."},{"name":"autostart","type":"boolean","required":false,"description":"Automatic restart after crash (currently ignored).","default":0},{"name":"balloon","type":"integer","required":false,"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},{"name":"bios","type":"string","required":false,"description":"Select BIOS implementation.","enum":["seabios","ovmf"],"default":"seabios"},{"name":"boot","type":"string","required":false,"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","format":"pve-qm-boot"},{"name":"bootdisk","type":"string","required":false,"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","format":"pve-qm-bootdisk"},{"name":"bwlimit","type":"integer","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"restore limit from datacenter or storage config"},{"name":"cdrom","type":"string","required":false,"description":"This is an alias for option -ide2","format":"pve-qm-ide"},{"name":"cicustom","type":"string","required":false,"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","format":"pve-qm-cicustom"},{"name":"cipassword","type":"string","required":false,"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."},{"name":"citype","type":"string","required":false,"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"]},{"name":"ciupgrade","type":"boolean","required":false,"description":"cloud-init: do an automatic package upgrade after the first boot.","default":1},{"name":"ciuser","type":"string","required":false,"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user."},{"name":"cores","type":"integer","required":false,"description":"The number of cores per socket.","default":1,"minimum":1},{"name":"cpu","type":"string","required":false,"description":"Emulated CPU type.","format":"pve-vm-cpu-conf"},{"name":"cpulimit","type":"number","required":false,"description":"Limit of CPU usage.","default":0,"minimum":0,"maximum":128},{"name":"cpuunits","type":"integer","required":false,"description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","default":"cgroup v1: 1024, cgroup v2: 100","minimum":1,"maximum":262144},{"name":"description","type":"string","required":false,"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file."},{"name":"efidisk0","type":"string","required":false,"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."},{"name":"force","type":"boolean","required":false,"description":"Allow to overwrite existing VM."},{"name":"freeze","type":"boolean","required":false,"description":"Freeze CPU at startup (use 'c' monitor command to start execution)."},{"name":"ha-managed","type":"boolean","required":false,"description":"Add the VM as a HA resource after it was created.","default":0},{"name":"hookscript","type":"string","required":false,"description":"Script that will be executed during various steps in the vms lifetime.","format":"pve-volume-id"},{"name":"hostpci[n]","type":"string","required":false,"description":"Map host PCI devices into guest.","format":"pve-qm-hostpci"},{"name":"hotplug","type":"string","required":false,"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.","default":"network,disk,usb","format":"pve-hotplug-features"},{"name":"hugepages","type":"string","required":false,"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"]},{"name":"ide[n]","type":"string","required":false,"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."},{"name":"import-working-storage","type":"string","required":false,"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"},{"name":"intel-tdx","type":"string","required":false,"description":"Trusted Domain Extension (TDX) features by Intel CPUs","format":"pve-qemu-tdx-fmt"},{"name":"ipconfig[n]","type":"string","required":false,"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.","format":"pve-qm-ipconfig"},{"name":"ivshmem","type":"string","required":false,"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host."},{"name":"keephugepages","type":"boolean","required":false,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","default":0},{"name":"keyboard","type":"string","required":false,"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"],"default":null},{"name":"kvm","type":"boolean","required":false,"description":"Enable/disable KVM hardware virtualization.","default":1},{"name":"live-restore","type":"boolean","required":false,"description":"Start the VM immediately while importing or restoring in the background."},{"name":"localtime","type":"boolean","required":false,"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS."},{"name":"lock","type":"string","required":false,"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"]},{"name":"machine","type":"string","required":false,"description":"Specify the QEMU machine."},{"name":"memory","type":"string","required":false,"description":"Memory properties."},{"name":"migrate_downtime","type":"number","required":false,"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).","default":0.1,"minimum":0},{"name":"migrate_speed","type":"integer","required":false,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","default":0,"minimum":0},{"name":"name","type":"string","required":false,"description":"Set a name for the VM. Only used on the configuration web interface.","format":"dns-name"},{"name":"nameserver","type":"string","required":false,"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"},{"name":"net[n]","type":"string","required":false,"description":"Specify network devices."},{"name":"numa","type":"boolean","required":false,"description":"Enable/disable NUMA.","default":0},{"name":"numa[n]","type":"string","required":false,"description":"NUMA topology."},{"name":"onboot","type":"boolean","required":false,"description":"Specifies whether a VM will be started during system bootup.","default":0},{"name":"ostype","type":"string","required":false,"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"default":"other"},{"name":"parallel[n]","type":"string","required":false,"description":"Map host parallel devices (n is 0 to 2)."},{"name":"pool","type":"string","required":false,"description":"Add the VM to the specified pool.","format":"pve-poolid"},{"name":"protection","type":"boolean","required":false,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","default":0},{"name":"reboot","type":"boolean","required":false,"description":"Allow reboot. If set to '0' the VM exit on reboot.","default":1},{"name":"rng0","type":"string","required":false,"description":"Configure a VirtIO-based Random Number Generator.","format":"pve-qm-rng"},{"name":"sata[n]","type":"string","required":false,"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."},{"name":"scsi[n]","type":"string","required":false,"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."},{"name":"scsihw","type":"string","required":false,"description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"default":"lsi"},{"name":"searchdomain","type":"string","required":false,"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."},{"name":"serial[n]","type":"string","required":false,"description":"Create a serial device inside the VM (n is 0 to 3)"},{"name":"shares","type":"integer","required":false,"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.","default":1000,"minimum":0,"maximum":50000},{"name":"smbios1","type":"string","required":false,"description":"Specify SMBIOS type 1 fields.","format":"pve-qm-smbios1"},{"name":"smp","type":"integer","required":false,"description":"The number of CPUs. Please use option -sockets instead.","default":1,"minimum":1},{"name":"sockets","type":"integer","required":false,"description":"The number of CPU sockets.","default":1,"minimum":1},{"name":"spice_enhancements","type":"string","required":false,"description":"Configure additional enhancements for SPICE."},{"name":"sshkeys","type":"string","required":false,"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","format":"urlencoded"},{"name":"start","type":"boolean","required":false,"description":"Start VM after it was created successfully.","default":0},{"name":"startdate","type":"string","required":false,"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'.","default":"now"},{"name":"startup","type":"string","required":false,"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"},{"name":"storage","type":"string","required":false,"description":"Default storage.","format":"pve-storage-id"},{"name":"tablet","type":"boolean","required":false,"description":"Enable/disable the USB tablet device.","default":1},{"name":"tags","type":"string","required":false,"description":"Tags of the VM. This is only meta information.","format":"pve-tag-list"},{"name":"tdf","type":"boolean","required":false,"description":"Enable/disable time drift fix.","default":0},{"name":"template","type":"boolean","required":false,"description":"Enable/disable Template.","default":0},{"name":"tpmstate0","type":"string","required":false,"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."},{"name":"unique","type":"boolean","required":false,"description":"Assign a unique random ethernet address."},{"name":"unused[n]","type":"string","required":false,"description":"Reference to unused volumes. This is used internally, and should not be modified manually."},{"name":"usb[n]","type":"string","required":false,"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)."},{"name":"vcpus","type":"integer","required":false,"description":"Number of hotplugged vcpus.","default":0,"minimum":1},{"name":"vga","type":"string","required":false,"description":"Configure the VGA hardware."},{"name":"virtio[n]","type":"string","required":false,"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."},{"name":"virtiofs[n]","type":"string","required":false,"description":"Configuration for sharing a directory between host and guest using Virtio-fs."},{"name":"vmgenid","type":"string","required":false,"description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","default":"1 (autogenerated)"},{"name":"vmstatestorage","type":"string","required":false,"description":"Default storage for VM state volumes/files.","format":"pve-storage-id"},{"name":"watchdog","type":"string","required":false,"description":"Create a virtual hardware watchdog device.","format":"pve-qm-watchdog"}],"returns":{"type":"string"},"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"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu\nnodes\ncreate_vm\nCreate or restore a virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\narchive string 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.\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\nefidisk0 string 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.\nforce boolean Allow to overwrite existing VM.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nha-managed boolean Add the VM as a HA resource after it was created.\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nimport-working-storage string A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlive-restore boolean Start the VM immediately while importing or restoring in the background.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\npool string Add the VM to the specified pool.\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstart boolean Start VM after it was created successfully.\nstartdate string 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'.\nstartup string 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.\nstorage string Default storage.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunique boolean Assign a unique random ethernet address.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest"} +{"id":"DELETE /nodes/{node}/qemu/{vmid}","method":"DELETE","path":"/nodes/{node}/qemu/{vmid}","section":"nodes","summary":"destroy_vm","description":"Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"destroy-unreferenced-disks","type":"boolean","required":false,"description":"If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.","default":0},{"name":"purge","type":"boolean","required":false,"description":"Remove VMID from configurations, like backup & replication jobs and HA."},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/qemu/{vmid}\nnodes\ndestroy_vm\nDestroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndestroy-unreferenced-disks boolean If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.\npurge boolean Remove VMID from configurations, like backup & replication jobs and HA.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}","method":"GET","path":"/nodes/{node}/qemu/{vmid}","section":"nodes","summary":"vmdiridx","description":"Directory index","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}\nnodes\nvmdiridx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent","section":"nodes","summary":"index","description":"QEMU Guest Agent command index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns the list of QEMU Guest Agent commands","items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent\nnodes\nindex\nQEMU Guest Agent command index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent","section":"nodes","summary":"agent","description":"Execute QEMU Guest Agent commands.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"command","type":"string","required":true,"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"]}],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent\nnodes\nagent\nExecute QEMU Guest Agent commands.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand string The QGA command. 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\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/exec","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/exec","section":"nodes","summary":"exec","description":"Executes the given command in the vm via the guest-agent and returns an object with the pid.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"command","type":"array","required":true,"description":"The command as a list of program + arguments."},{"name":"input-data","type":"string","required":false,"description":"Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'."}],"returns":{"properties":{"pid":{"description":"The PID of the process started by the guest-agent.","type":"integer"}},"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/exec\nnodes\nexec\nExecutes the given command in the vm via the guest-agent and returns an object with the pid.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand array The command as a list of program + arguments.\ninput-data string Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/exec-status","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/exec-status","section":"nodes","summary":"exec-status","description":"Gets the status of the given pid started by the guest-agent","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"pid","type":"integer","required":true,"description":"The PID to query"}],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/exec-status\nnodes\nexec-status\nGets the status of the given pid started by the guest-agent\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npid integer The PID to query\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/file-read","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/file-read","section":"nodes","summary":"file-read","description":"Reads the given file via guest agent. Is limited to 16777216 bytes.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"file","type":"string","required":true,"description":"The path to the file"},{"name":"count","type":"integer","required":false,"description":"Number of bytes to read.","default":"16777216","minimum":1},{"name":"decode","type":"boolean","required":false,"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.","default":1},{"name":"offset","type":"integer","required":false,"description":"Offset to start reading at","default":0,"minimum":0}],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileRead","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/file-read\nnodes\nfile-read\nReads the given file via guest agent. Is limited to 16777216 bytes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfile string The path to the file\ncount integer Number of bytes to read.\ndecode boolean 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.\noffset integer Offset to start reading at\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/file-write","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/file-write","section":"nodes","summary":"file-write","description":"Writes the given file via guest agent.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"content","type":"string","required":true,"description":"The content to write into the file."},{"name":"file","type":"string","required":true,"description":"The path to the file."},{"name":"encode","type":"boolean","required":false,"description":"If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.","default":1}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileWrite","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/file-write\nnodes\nfile-write\nWrites the given file via guest agent.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontent string The content to write into the file.\nfile string The path to the file.\nencode boolean If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze","section":"nodes","summary":"fsfreeze-freeze","description":"Execute fsfreeze-freeze.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze\nnodes\nfsfreeze-freeze\nExecute fsfreeze-freeze.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-status","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status","section":"nodes","summary":"fsfreeze-status","description":"Execute fsfreeze-status.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status\nnodes\nfsfreeze-status\nExecute fsfreeze-status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw","section":"nodes","summary":"fsfreeze-thaw","description":"Execute fsfreeze-thaw.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw\nnodes\nfsfreeze-thaw\nExecute fsfreeze-thaw.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/fstrim","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/fstrim","section":"nodes","summary":"fstrim","description":"Execute fstrim.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.FileSystemMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/fstrim\nnodes\nfstrim\nExecute fstrim.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-fsinfo","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-fsinfo","section":"nodes","summary":"get-fsinfo","description":"Execute get-fsinfo.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-fsinfo\nnodes\nget-fsinfo\nExecute get-fsinfo.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-host-name","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-host-name","section":"nodes","summary":"get-host-name","description":"Execute get-host-name.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-host-name\nnodes\nget-host-name\nExecute get-host-name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-memory-block-info","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info","section":"nodes","summary":"get-memory-block-info","description":"Execute get-memory-block-info.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info\nnodes\nget-memory-block-info\nExecute get-memory-block-info.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-memory-blocks","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks","section":"nodes","summary":"get-memory-blocks","description":"Execute get-memory-blocks.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks\nnodes\nget-memory-blocks\nExecute get-memory-blocks.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-osinfo","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-osinfo","section":"nodes","summary":"get-osinfo","description":"Execute get-osinfo.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-osinfo\nnodes\nget-osinfo\nExecute get-osinfo.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-time","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-time","section":"nodes","summary":"get-time","description":"Execute get-time.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-time\nnodes\nget-time\nExecute get-time.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-timezone","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-timezone","section":"nodes","summary":"get-timezone","description":"Execute get-timezone.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-timezone\nnodes\nget-timezone\nExecute get-timezone.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-users","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-users","section":"nodes","summary":"get-users","description":"Execute get-users.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-users\nnodes\nget-users\nExecute get-users.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/get-vcpus","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/get-vcpus","section":"nodes","summary":"get-vcpus","description":"Execute get-vcpus.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/get-vcpus\nnodes\nget-vcpus\nExecute get-vcpus.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/info","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/info","section":"nodes","summary":"info","description":"Execute info.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/info\nnodes\ninfo\nExecute info.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces","method":"GET","path":"/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces","section":"nodes","summary":"network-get-interfaces","description":"Execute network-get-interfaces.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces\nnodes\nnetwork-get-interfaces\nExecute network-get-interfaces.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/ping","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/ping","section":"nodes","summary":"ping","description":"Execute ping.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Audit","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/ping\nnodes\nping\nExecute ping.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/set-user-password","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/set-user-password","section":"nodes","summary":"set-user-password","description":"Sets the password for the given user to the given password","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"password","type":"string","required":true,"description":"The new password."},{"name":"username","type":"string","required":true,"description":"The user to set the password for."},{"name":"crypted","type":"boolean","required":false,"description":"set to 1 if the password has already been passed through crypt()","default":0}],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.GuestAgent.Unrestricted"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/set-user-password\nnodes\nset-user-password\nSets the password for the given user to the given password\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npassword string The new password.\nusername string The user to set the password for.\ncrypted boolean set to 1 if the password has already been passed through crypt()\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/shutdown","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/shutdown","section":"nodes","summary":"shutdown","description":"Execute shutdown.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/shutdown\nnodes\nshutdown\nExecute shutdown.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/suspend-disk","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/suspend-disk","section":"nodes","summary":"suspend-disk","description":"Execute suspend-disk.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-disk\nnodes\nsuspend-disk\nExecute suspend-disk.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/suspend-hybrid","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid","section":"nodes","summary":"suspend-hybrid","description":"Execute suspend-hybrid.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid\nnodes\nsuspend-hybrid\nExecute suspend-hybrid.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/agent/suspend-ram","method":"POST","path":"/nodes/{node}/qemu/{vmid}/agent/suspend-ram","section":"nodes","summary":"suspend-ram","description":"Execute suspend-ram.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"description":"Returns an object with a single `result` property.","type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt","VM.GuestAgent.Unrestricted"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-ram\nnodes\nsuspend-ram\nExecute suspend-ram.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/clone","method":"POST","path":"/nodes/{node}/qemu/{vmid}/clone","section":"nodes","summary":"clone_vm","description":"Create a copy of virtual machine/template.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"newid","type":"integer","required":true,"description":"VMID for the clone.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"bwlimit","type":"integer","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"clone limit from datacenter or storage config"},{"name":"description","type":"string","required":false,"description":"Description for the new VM."},{"name":"format","type":"string","required":false,"description":"Target format for file storage. Only valid for full clone.","enum":["raw","qcow2","vmdk"]},{"name":"full","type":"boolean","required":false,"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."},{"name":"name","type":"string","required":false,"description":"Set a name for the new VM.","format":"dns-name"},{"name":"pool","type":"string","required":false,"description":"Add the new VM to the specified pool.","format":"pve-poolid"},{"name":"snapname","type":"string","required":false,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"storage","type":"string","required":false,"description":"Target storage for full clone.","format":"pve-storage-id"},{"name":"target","type":"string","required":false,"description":"Target node. Only allowed if the original VM is on shared storage.","format":"pve-node"}],"returns":{"type":"string"},"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"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/clone\nnodes\nclone_vm\nCreate a copy of virtual machine/template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnewid integer VMID for the clone.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndescription string Description for the new VM.\nformat string Target format for file storage. Only valid for full clone. raw qcow2 vmdk\nfull boolean 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.\nname string Set a name for the new VM.\npool string Add the new VM to the specified pool.\nsnapname string The name of the snapshot.\nstorage string Target storage for full clone.\ntarget string Target node. Only allowed if the original VM is on shared storage.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template"} +{"id":"GET /nodes/{node}/qemu/{vmid}/cloudinit","method":"GET","path":"/nodes/{node}/qemu/{vmid}/cloudinit","section":"nodes","summary":"cloudinit_pending","description":"Get the cloudinit configuration with both current and pending values.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/cloudinit\nnodes\ncloudinit_pending\nGet the cloudinit configuration with both current and pending values.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/cloudinit","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/cloudinit","section":"nodes","summary":"cloudinit_update","description":"Regenerate and change cloudinit config drive.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Cloudinit"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/cloudinit\nnodes\ncloudinit_update\nRegenerate and change cloudinit config drive.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/cloudinit/dump","method":"GET","path":"/nodes/{node}/qemu/{vmid}/cloudinit/dump","section":"nodes","summary":"cloudinit_generated_config_dump","description":"Get automatically generated cloudinit config.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"type","type":"string","required":true,"description":"Config type.","enum":["user","network","meta"]}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/cloudinit/dump\nnodes\ncloudinit_generated_config_dump\nGet automatically generated cloudinit config.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Config type. user network meta\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/config","method":"GET","path":"/nodes/{node}/qemu/{vmid}/config","section":"nodes","summary":"vm_config","description":"Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"current","type":"boolean","required":false,"description":"Get current values (instead of pending values).","default":0},{"name":"snapshot","type":"string","required":false,"description":"Fetch config values from given snapshot.","format":"pve-configid"}],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/config\nnodes\nvm_config\nGet the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncurrent boolean Get current values (instead of pending values).\nsnapshot string Fetch config values from given snapshot.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/config","method":"POST","path":"/nodes/{node}/qemu/{vmid}/config","section":"nodes","summary":"update_vm_async","description":"Set virtual machine options (asynchronous API).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"acpi","type":"boolean","required":false,"description":"Enable/disable ACPI.","default":1},{"name":"affinity","type":"string","required":false,"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","format":"pve-cpuset"},{"name":"agent","type":"string","required":false,"description":"Enable/disable communication with the QEMU Guest Agent and its properties."},{"name":"allow-ksm","type":"boolean","required":false,"description":"Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).","default":1},{"name":"amd-sev","type":"string","required":false,"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","format":"pve-qemu-sev-fmt"},{"name":"arch","type":"string","required":false,"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"]},{"name":"args","type":"string","required":false,"description":"Arbitrary arguments passed to kvm."},{"name":"audio0","type":"string","required":false,"description":"Configure a audio device, useful in combination with QXL/Spice."},{"name":"autostart","type":"boolean","required":false,"description":"Automatic restart after crash (currently ignored).","default":0},{"name":"background_delay","type":"integer","required":false,"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","minimum":1,"maximum":30},{"name":"balloon","type":"integer","required":false,"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},{"name":"bios","type":"string","required":false,"description":"Select BIOS implementation.","enum":["seabios","ovmf"],"default":"seabios"},{"name":"boot","type":"string","required":false,"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","format":"pve-qm-boot"},{"name":"bootdisk","type":"string","required":false,"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","format":"pve-qm-bootdisk"},{"name":"cdrom","type":"string","required":false,"description":"This is an alias for option -ide2","format":"pve-qm-ide"},{"name":"cicustom","type":"string","required":false,"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","format":"pve-qm-cicustom"},{"name":"cipassword","type":"string","required":false,"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."},{"name":"citype","type":"string","required":false,"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"]},{"name":"ciupgrade","type":"boolean","required":false,"description":"cloud-init: do an automatic package upgrade after the first boot.","default":1},{"name":"ciuser","type":"string","required":false,"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user."},{"name":"cores","type":"integer","required":false,"description":"The number of cores per socket.","default":1,"minimum":1},{"name":"cpu","type":"string","required":false,"description":"Emulated CPU type.","format":"pve-vm-cpu-conf"},{"name":"cpulimit","type":"number","required":false,"description":"Limit of CPU usage.","default":0,"minimum":0,"maximum":128},{"name":"cpuunits","type":"integer","required":false,"description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","default":"cgroup v1: 1024, cgroup v2: 100","minimum":1,"maximum":262144},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications."},{"name":"efidisk0","type":"string","required":false,"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."},{"name":"force","type":"boolean","required":false,"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."},{"name":"freeze","type":"boolean","required":false,"description":"Freeze CPU at startup (use 'c' monitor command to start execution)."},{"name":"hookscript","type":"string","required":false,"description":"Script that will be executed during various steps in the vms lifetime.","format":"pve-volume-id"},{"name":"hostpci[n]","type":"string","required":false,"description":"Map host PCI devices into guest.","format":"pve-qm-hostpci"},{"name":"hotplug","type":"string","required":false,"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.","default":"network,disk,usb","format":"pve-hotplug-features"},{"name":"hugepages","type":"string","required":false,"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"]},{"name":"ide[n]","type":"string","required":false,"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."},{"name":"import-working-storage","type":"string","required":false,"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"},{"name":"intel-tdx","type":"string","required":false,"description":"Trusted Domain Extension (TDX) features by Intel CPUs","format":"pve-qemu-tdx-fmt"},{"name":"ipconfig[n]","type":"string","required":false,"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.","format":"pve-qm-ipconfig"},{"name":"ivshmem","type":"string","required":false,"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host."},{"name":"keephugepages","type":"boolean","required":false,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","default":0},{"name":"keyboard","type":"string","required":false,"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"],"default":null},{"name":"kvm","type":"boolean","required":false,"description":"Enable/disable KVM hardware virtualization.","default":1},{"name":"localtime","type":"boolean","required":false,"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS."},{"name":"lock","type":"string","required":false,"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"]},{"name":"machine","type":"string","required":false,"description":"Specify the QEMU machine."},{"name":"memory","type":"string","required":false,"description":"Memory properties."},{"name":"migrate_downtime","type":"number","required":false,"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).","default":0.1,"minimum":0},{"name":"migrate_speed","type":"integer","required":false,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","default":0,"minimum":0},{"name":"name","type":"string","required":false,"description":"Set a name for the VM. Only used on the configuration web interface.","format":"dns-name"},{"name":"nameserver","type":"string","required":false,"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"},{"name":"net[n]","type":"string","required":false,"description":"Specify network devices."},{"name":"numa","type":"boolean","required":false,"description":"Enable/disable NUMA.","default":0},{"name":"numa[n]","type":"string","required":false,"description":"NUMA topology."},{"name":"onboot","type":"boolean","required":false,"description":"Specifies whether a VM will be started during system bootup.","default":0},{"name":"ostype","type":"string","required":false,"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"default":"other"},{"name":"parallel[n]","type":"string","required":false,"description":"Map host parallel devices (n is 0 to 2)."},{"name":"protection","type":"boolean","required":false,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","default":0},{"name":"reboot","type":"boolean","required":false,"description":"Allow reboot. If set to '0' the VM exit on reboot.","default":1},{"name":"revert","type":"string","required":false,"description":"Revert a pending change.","format":"pve-configid-list"},{"name":"rng0","type":"string","required":false,"description":"Configure a VirtIO-based Random Number Generator.","format":"pve-qm-rng"},{"name":"sata[n]","type":"string","required":false,"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."},{"name":"scsi[n]","type":"string","required":false,"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."},{"name":"scsihw","type":"string","required":false,"description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"default":"lsi"},{"name":"searchdomain","type":"string","required":false,"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."},{"name":"serial[n]","type":"string","required":false,"description":"Create a serial device inside the VM (n is 0 to 3)"},{"name":"shares","type":"integer","required":false,"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.","default":1000,"minimum":0,"maximum":50000},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."},{"name":"smbios1","type":"string","required":false,"description":"Specify SMBIOS type 1 fields.","format":"pve-qm-smbios1"},{"name":"smp","type":"integer","required":false,"description":"The number of CPUs. Please use option -sockets instead.","default":1,"minimum":1},{"name":"sockets","type":"integer","required":false,"description":"The number of CPU sockets.","default":1,"minimum":1},{"name":"spice_enhancements","type":"string","required":false,"description":"Configure additional enhancements for SPICE."},{"name":"sshkeys","type":"string","required":false,"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","format":"urlencoded"},{"name":"startdate","type":"string","required":false,"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'.","default":"now"},{"name":"startup","type":"string","required":false,"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"},{"name":"tablet","type":"boolean","required":false,"description":"Enable/disable the USB tablet device.","default":1},{"name":"tags","type":"string","required":false,"description":"Tags of the VM. This is only meta information.","format":"pve-tag-list"},{"name":"tdf","type":"boolean","required":false,"description":"Enable/disable time drift fix.","default":0},{"name":"template","type":"boolean","required":false,"description":"Enable/disable Template.","default":0},{"name":"tpmstate0","type":"string","required":false,"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."},{"name":"unused[n]","type":"string","required":false,"description":"Reference to unused volumes. This is used internally, and should not be modified manually."},{"name":"usb[n]","type":"string","required":false,"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)."},{"name":"vcpus","type":"integer","required":false,"description":"Number of hotplugged vcpus.","default":0,"minimum":1},{"name":"vga","type":"string","required":false,"description":"Configure the VGA hardware."},{"name":"virtio[n]","type":"string","required":false,"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."},{"name":"virtiofs[n]","type":"string","required":false,"description":"Configuration for sharing a directory between host and guest using Virtio-fs."},{"name":"vmgenid","type":"string","required":false,"description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","default":"1 (autogenerated)"},{"name":"vmstatestorage","type":"string","required":false,"description":"Default storage for VM state volumes/files.","format":"pve-storage-id"},{"name":"watchdog","type":"string","required":false,"description":"Create a virtual hardware watchdog device.","format":"pve-qm-watchdog"}],"returns":{"optional":1,"type":"string"},"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]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/config\nnodes\nupdate_vm_async\nSet virtual machine options (asynchronous API).\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nbackground_delay integer Time to wait for the task to finish. We return 'null' if the task finish within that time.\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndelete string A list of settings you want to delete.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nefidisk0 string 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.\nforce boolean 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.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nimport-working-storage string A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrevert string Revert a pending change.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstartdate string 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'.\nstartup string 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.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/config","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/config","section":"nodes","summary":"update_vm","description":"Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"acpi","type":"boolean","required":false,"description":"Enable/disable ACPI.","default":1},{"name":"affinity","type":"string","required":false,"description":"List of host cores used to execute guest processes, for example: 0,5,8-11","format":"pve-cpuset"},{"name":"agent","type":"string","required":false,"description":"Enable/disable communication with the QEMU Guest Agent and its properties."},{"name":"allow-ksm","type":"boolean","required":false,"description":"Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).","default":1},{"name":"amd-sev","type":"string","required":false,"description":"Secure Encrypted Virtualization (SEV) features by AMD CPUs","format":"pve-qemu-sev-fmt"},{"name":"arch","type":"string","required":false,"description":"Virtual processor architecture. Defaults to the host architecture.","enum":["x86_64","aarch64"]},{"name":"args","type":"string","required":false,"description":"Arbitrary arguments passed to kvm."},{"name":"audio0","type":"string","required":false,"description":"Configure a audio device, useful in combination with QXL/Spice."},{"name":"autostart","type":"boolean","required":false,"description":"Automatic restart after crash (currently ignored).","default":0},{"name":"balloon","type":"integer","required":false,"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},{"name":"bios","type":"string","required":false,"description":"Select BIOS implementation.","enum":["seabios","ovmf"],"default":"seabios"},{"name":"boot","type":"string","required":false,"description":"Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.","format":"pve-qm-boot"},{"name":"bootdisk","type":"string","required":false,"description":"Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.","format":"pve-qm-bootdisk"},{"name":"cdrom","type":"string","required":false,"description":"This is an alias for option -ide2","format":"pve-qm-ide"},{"name":"cicustom","type":"string","required":false,"description":"cloud-init: Specify custom files to replace the automatically generated ones at start.","format":"pve-qm-cicustom"},{"name":"cipassword","type":"string","required":false,"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."},{"name":"citype","type":"string","required":false,"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"]},{"name":"ciupgrade","type":"boolean","required":false,"description":"cloud-init: do an automatic package upgrade after the first boot.","default":1},{"name":"ciuser","type":"string","required":false,"description":"cloud-init: User name to change ssh keys and password for instead of the image's configured default user."},{"name":"cores","type":"integer","required":false,"description":"The number of cores per socket.","default":1,"minimum":1},{"name":"cpu","type":"string","required":false,"description":"Emulated CPU type.","format":"pve-vm-cpu-conf"},{"name":"cpulimit","type":"number","required":false,"description":"Limit of CPU usage.","default":0,"minimum":0,"maximum":128},{"name":"cpuunits","type":"integer","required":false,"description":"CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.","default":"cgroup v1: 1024, cgroup v2: 100","minimum":1,"maximum":262144},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"description","type":"string","required":false,"description":"Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications."},{"name":"efidisk0","type":"string","required":false,"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."},{"name":"force","type":"boolean","required":false,"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."},{"name":"freeze","type":"boolean","required":false,"description":"Freeze CPU at startup (use 'c' monitor command to start execution)."},{"name":"hookscript","type":"string","required":false,"description":"Script that will be executed during various steps in the vms lifetime.","format":"pve-volume-id"},{"name":"hostpci[n]","type":"string","required":false,"description":"Map host PCI devices into guest.","format":"pve-qm-hostpci"},{"name":"hotplug","type":"string","required":false,"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.","default":"network,disk,usb","format":"pve-hotplug-features"},{"name":"hugepages","type":"string","required":false,"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"]},{"name":"ide[n]","type":"string","required":false,"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."},{"name":"intel-tdx","type":"string","required":false,"description":"Trusted Domain Extension (TDX) features by Intel CPUs","format":"pve-qemu-tdx-fmt"},{"name":"ipconfig[n]","type":"string","required":false,"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.","format":"pve-qm-ipconfig"},{"name":"ivshmem","type":"string","required":false,"description":"Inter-VM shared memory. Useful for direct communication between VMs, or to the host."},{"name":"keephugepages","type":"boolean","required":false,"description":"Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.","default":0},{"name":"keyboard","type":"string","required":false,"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"],"default":null},{"name":"kvm","type":"boolean","required":false,"description":"Enable/disable KVM hardware virtualization.","default":1},{"name":"localtime","type":"boolean","required":false,"description":"Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS."},{"name":"lock","type":"string","required":false,"description":"Lock/unlock the VM.","enum":["backup","clone","create","migrate","rollback","snapshot","snapshot-delete","suspending","suspended"]},{"name":"machine","type":"string","required":false,"description":"Specify the QEMU machine."},{"name":"memory","type":"string","required":false,"description":"Memory properties."},{"name":"migrate_downtime","type":"number","required":false,"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).","default":0.1,"minimum":0},{"name":"migrate_speed","type":"integer","required":false,"description":"Set maximum speed (in MB/s) for migrations. Value 0 is no limit.","default":0,"minimum":0},{"name":"name","type":"string","required":false,"description":"Set a name for the VM. Only used on the configuration web interface.","format":"dns-name"},{"name":"nameserver","type":"string","required":false,"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"},{"name":"net[n]","type":"string","required":false,"description":"Specify network devices."},{"name":"numa","type":"boolean","required":false,"description":"Enable/disable NUMA.","default":0},{"name":"numa[n]","type":"string","required":false,"description":"NUMA topology."},{"name":"onboot","type":"boolean","required":false,"description":"Specifies whether a VM will be started during system bootup.","default":0},{"name":"ostype","type":"string","required":false,"description":"Specify guest operating system.","enum":["other","wxp","w2k","w2k3","w2k8","wvista","win7","win8","win10","win11","l24","l26","solaris"],"default":"other"},{"name":"parallel[n]","type":"string","required":false,"description":"Map host parallel devices (n is 0 to 2)."},{"name":"protection","type":"boolean","required":false,"description":"Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.","default":0},{"name":"reboot","type":"boolean","required":false,"description":"Allow reboot. If set to '0' the VM exit on reboot.","default":1},{"name":"revert","type":"string","required":false,"description":"Revert a pending change.","format":"pve-configid-list"},{"name":"rng0","type":"string","required":false,"description":"Configure a VirtIO-based Random Number Generator.","format":"pve-qm-rng"},{"name":"sata[n]","type":"string","required":false,"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."},{"name":"scsi[n]","type":"string","required":false,"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."},{"name":"scsihw","type":"string","required":false,"description":"SCSI controller model","enum":["lsi","lsi53c810","virtio-scsi-pci","virtio-scsi-single","megasas","pvscsi"],"default":"lsi"},{"name":"searchdomain","type":"string","required":false,"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."},{"name":"serial[n]","type":"string","required":false,"description":"Create a serial device inside the VM (n is 0 to 3)"},{"name":"shares","type":"integer","required":false,"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.","default":1000,"minimum":0,"maximum":50000},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."},{"name":"smbios1","type":"string","required":false,"description":"Specify SMBIOS type 1 fields.","format":"pve-qm-smbios1"},{"name":"smp","type":"integer","required":false,"description":"The number of CPUs. Please use option -sockets instead.","default":1,"minimum":1},{"name":"sockets","type":"integer","required":false,"description":"The number of CPU sockets.","default":1,"minimum":1},{"name":"spice_enhancements","type":"string","required":false,"description":"Configure additional enhancements for SPICE."},{"name":"sshkeys","type":"string","required":false,"description":"cloud-init: Setup public SSH keys (one key per line, OpenSSH format).","format":"urlencoded"},{"name":"startdate","type":"string","required":false,"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'.","default":"now"},{"name":"startup","type":"string","required":false,"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"},{"name":"tablet","type":"boolean","required":false,"description":"Enable/disable the USB tablet device.","default":1},{"name":"tags","type":"string","required":false,"description":"Tags of the VM. This is only meta information.","format":"pve-tag-list"},{"name":"tdf","type":"boolean","required":false,"description":"Enable/disable time drift fix.","default":0},{"name":"template","type":"boolean","required":false,"description":"Enable/disable Template.","default":0},{"name":"tpmstate0","type":"string","required":false,"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."},{"name":"unused[n]","type":"string","required":false,"description":"Reference to unused volumes. This is used internally, and should not be modified manually."},{"name":"usb[n]","type":"string","required":false,"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)."},{"name":"vcpus","type":"integer","required":false,"description":"Number of hotplugged vcpus.","default":0,"minimum":1},{"name":"vga","type":"string","required":false,"description":"Configure the VGA hardware."},{"name":"virtio[n]","type":"string","required":false,"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."},{"name":"virtiofs[n]","type":"string","required":false,"description":"Configuration for sharing a directory between host and guest using Virtio-fs."},{"name":"vmgenid","type":"string","required":false,"description":"Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.","default":"1 (autogenerated)"},{"name":"vmstatestorage","type":"string","required":false,"description":"Default storage for VM state volumes/files.","format":"pve-storage-id"},{"name":"watchdog","type":"string","required":false,"description":"Create a virtual hardware watchdog device.","format":"pve-qm-watchdog"}],"returns":{"type":"null"},"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]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/config\nnodes\nupdate_vm\nSet virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndelete string A list of settings you want to delete.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nefidisk0 string 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.\nforce boolean 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.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrevert string Revert a pending change.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstartdate string 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'.\nstartup string 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.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/dbus-vmstate","method":"POST","path":"/nodes/{node}/qemu/{vmid}/dbus-vmstate","section":"nodes","summary":"dbus_vmstate","description":"Control the dbus-vmstate helper for a given running VM.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Action to perform on the DBus VMState helper.","enum":["start","stop"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/dbus-vmstate\nnodes\ndbus_vmstate\nControl the dbus-vmstate helper for a given running VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Action to perform on the DBus VMState helper. start stop\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/feature","method":"GET","path":"/nodes/{node}/qemu/{vmid}/feature","section":"nodes","summary":"vm_feature","description":"Check if feature for virtual machine is available.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"feature","type":"string","required":true,"description":"Feature to check.","enum":["snapshot","clone","copy"]},{"name":"snapname","type":"string","required":false,"description":"The name of the snapshot.","format":"pve-configid"}],"returns":{"properties":{"hasFeature":{"type":"boolean"},"nodes":{"items":{"type":"string"},"type":"array"}},"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/feature\nnodes\nvm_feature\nCheck if feature for virtual machine is available.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfeature string Feature to check. snapshot clone copy\nsnapname string The name of the snapshot.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall","section":"nodes","summary":"index","description":"Directory index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/aliases","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/aliases","section":"nodes","summary":"get_aliases","description":"List aliases","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/aliases\nnodes\nget_aliases\nList aliases\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/firewall/aliases","method":"POST","path":"/nodes/{node}/qemu/{vmid}/firewall/aliases","section":"nodes","summary":"create_alias","description":"Create IP or Network Alias.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDR"},{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"comment","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/firewall/aliases\nnodes\ncreate_alias\nCreate IP or Network Alias.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}","method":"DELETE","path":"/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}","section":"nodes","summary":"remove_alias","description":"Remove IP or Network alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}","section":"nodes","summary":"read_alias","description":"Read alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nread_alias\nRead alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}","section":"nodes","summary":"update_alias","description":"Update IP or Network alias.","pathParameters":[{"name":"name","type":"string","required":true,"description":"Alias name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDR"},{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"rename","type":"string","required":false,"description":"Rename an existing alias."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/ipset","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset","section":"nodes","summary":"ipset_index","description":"List IPSets","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset\nnodes\nipset_index\nList IPSets\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/firewall/ipset","method":"POST","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset","section":"nodes","summary":"create_ipset","description":"Create new IPSet","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"rename","type":"string","required":false,"description":"Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/firewall/ipset\nnodes\ncreate_ipset\nCreate new IPSet\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}","method":"DELETE","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}","section":"nodes","summary":"delete_ipset","description":"Delete IPSet","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Delete all members of the IPSet, if there are any."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\ndelete_ipset\nDelete IPSet\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce boolean Delete all members of the IPSet, if there are any.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}","section":"nodes","summary":"get_ipset","description":"List IPSet content","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\nget_ipset\nList IPSet content\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}","method":"POST","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}","section":"nodes","summary":"create_ip","description":"Add IP or Network to IPSet.","pathParameters":[{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"comment","type":"string","required":false},{"name":"nomatch","type":"boolean","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}","method":"DELETE","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}","section":"nodes","summary":"remove_ip","description":"Remove IP or Network from IPSet.","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}","section":"nodes","summary":"read_ip","description":"Read IP or Network settings from IPSet.","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}","section":"nodes","summary":"update_ip","description":"Update IP or Network settings","pathParameters":[{"name":"cidr","type":"string","required":true,"description":"Network/IP specification in CIDR format.","format":"IPorCIDRorAlias"},{"name":"name","type":"string","required":true,"description":"IP set name."},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"comment","type":"string","required":false},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"nomatch","type":"boolean","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/log","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/log","section":"nodes","summary":"log","description":"Read firewall log","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"limit","type":"integer","required":false,"minimum":0},{"name":"since","type":"integer","required":false,"description":"Display log since this UNIX epoch.","minimum":0},{"name":"start","type":"integer","required":false,"minimum":0},{"name":"until","type":"integer","required":false,"description":"Display log until this UNIX epoch.","minimum":0}],"returns":{"items":{"properties":{"n":{"description":"Line number","type":"integer"},"t":{"description":"Line text","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/options","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/options","section":"nodes","summary":"get_options","description":"Get VM firewall options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/options\nnodes\nget_options\nGet VM firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/firewall/options","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/firewall/options","section":"nodes","summary":"set_options","description":"Set Firewall options.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dhcp","type":"boolean","required":false,"description":"Enable DHCP.","default":0},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"enable","type":"boolean","required":false,"description":"Enable/disable firewall rules.","default":0},{"name":"ipfilter","type":"boolean","required":false,"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."},{"name":"log_level_in","type":"string","required":false,"description":"Log level for incoming traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"log_level_out","type":"string","required":false,"description":"Log level for outgoing traffic.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macfilter","type":"boolean","required":false,"description":"Enable/disable MAC address filter.","default":1},{"name":"ndp","type":"boolean","required":false,"description":"Enable NDP (Neighbor Discovery Protocol).","default":1},{"name":"policy_in","type":"string","required":false,"description":"Input policy.","enum":["ACCEPT","REJECT","DROP"]},{"name":"policy_out","type":"string","required":false,"description":"Output policy.","enum":["ACCEPT","REJECT","DROP"]},{"name":"radv","type":"boolean","required":false,"description":"Allow sending Router Advertisement."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndelete string A list of settings you want to delete.\ndhcp boolean Enable DHCP.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nipfilter boolean 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.\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nmacfilter boolean Enable/disable MAC address filter.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP\nradv boolean Allow sending Router Advertisement.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/refs","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/refs","section":"nodes","summary":"refs","description":"Lists possible IPSet/Alias reference which are allowed in source/dest properties.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list references of specified type.","enum":["alias","ipset"]}],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/refs\nnodes\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Only list references of specified type. alias ipset\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/rules","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/rules","section":"nodes","summary":"get_rules","description":"List rules.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/firewall/rules","method":"POST","path":"/nodes/{node}/qemu/{vmid}/firewall/rules","section":"nodes","summary":"create_rule","description":"Create new rule.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"action","type":"string","required":true,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"type","type":"string","required":true,"description":"Rule type.","enum":["in","out","forward","group"]},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"DELETE /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}","method":"DELETE","path":"/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}","section":"nodes","summary":"delete_rule","description":"Delete rule.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}","method":"GET","path":"/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}","section":"nodes","summary":"get_rule","description":"Get single rule data.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}","section":"nodes","summary":"update_rule","description":"Modify rule data.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"pos","type":"integer","required":false,"description":"Update rule at position .","minimum":0}],"requestParameters":[{"name":"action","type":"string","required":false,"description":"Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name."},{"name":"comment","type":"string","required":false,"description":"Descriptive comment."},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"dest","type":"string","required":false,"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"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"dport","type":"string","required":false,"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"},{"name":"enable","type":"integer","required":false,"description":"Flag to enable/disable a rule.","minimum":0},{"name":"icmp-type","type":"string","required":false,"description":"Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.","format":"pve-fw-icmp-type-spec"},{"name":"iface","type":"string","required":false,"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"},{"name":"log","type":"string","required":false,"description":"Log level for firewall rule.","enum":["emerg","alert","crit","err","warning","notice","info","debug","nolog"]},{"name":"macro","type":"string","required":false,"description":"Use predefined standard macro."},{"name":"moveto","type":"integer","required":false,"description":"Move rule to new position . Other arguments are ignored.","minimum":0},{"name":"proto","type":"string","required":false,"description":"IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.","format":"pve-fw-protocol-spec"},{"name":"source","type":"string","required":false,"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"},{"name":"sport","type":"string","required":false,"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"},{"name":"type","type":"string","required":false,"description":"Rule type.","enum":["in","out","forward","group"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Network"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/migrate","method":"GET","path":"/nodes/{node}/qemu/{vmid}/migrate","section":"nodes","summary":"migrate_vm_precondition","description":"Get preconditions for migration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"target","type":"string","required":false,"description":"Target node.","format":"pve-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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/migrate\nnodes\nmigrate_vm_precondition\nGet preconditions for migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/migrate","method":"POST","path":"/nodes/{node}/qemu/{vmid}/migrate","section":"nodes","summary":"migrate_vm","description":"Migrate virtual machine. Creates a new migration task.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"target","type":"string","required":true,"description":"Target node.","format":"pve-node"},{"name":"bwlimit","type":"integer","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"migrate limit from datacenter or storage config"},{"name":"force","type":"boolean","required":false,"description":"Allow to migrate VMs which use local devices. Only root may use this option."},{"name":"migration_network","type":"string","required":false,"description":"CIDR of the (sub) network that is used for migration.","format":"CIDR"},{"name":"migration_type","type":"string","required":false,"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"]},{"name":"online","type":"boolean","required":false,"description":"Use online/live migration if VM is running. Ignored if VM is stopped."},{"name":"targetstorage","type":"string","required":false,"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"},{"name":"with-conntrack-state","type":"boolean","required":false,"description":"Whether to migrate conntrack entries for running VMs.","default":0},{"name":"with-local-disks","type":"boolean","required":false,"description":"Enable live storage migration for local disk"}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/migrate\nnodes\nmigrate_vm\nMigrate virtual machine. Creates a new migration task.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\nforce boolean Allow to migrate VMs which use local devices. Only root may use this option.\nmigration_network string CIDR of the (sub) network that is used for migration.\nmigration_type string Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. secure insecure\nonline boolean Use online/live migration if VM is running. Ignored if VM is stopped.\ntargetstorage string 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.\nwith-conntrack-state boolean Whether to migrate conntrack entries for running VMs.\nwith-local-disks boolean Enable live storage migration for local disk\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/monitor","method":"POST","path":"/nodes/{node}/qemu/{vmid}/monitor","section":"nodes","summary":"monitor","description":"Execute QEMU monitor commands.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"command","type":"string","required":true,"description":"The monitor command."}],"returns":{"type":"string"},"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"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/monitor\nnodes\nmonitor\nExecute QEMU monitor commands.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand string The monitor command.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/move_disk","method":"POST","path":"/nodes/{node}/qemu/{vmid}/move_disk","section":"nodes","summary":"move_vm_disk","description":"Move volume to different storage or to a different VM.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"disk","type":"string","required":true,"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"]},{"name":"bwlimit","type":"integer","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"move limit from datacenter or storage config"},{"name":"delete","type":"boolean","required":false,"description":"Delete the original disk after successful copy. By default the original disk is kept as unused disk.","default":0},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications."},{"name":"format","type":"string","required":false,"description":"Target Format.","enum":["raw","qcow2","vmdk"]},{"name":"storage","type":"string","required":false,"description":"Target storage.","format":"pve-storage-id"},{"name":"target-digest","type":"string","required":false,"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."},{"name":"target-disk","type":"string","required":false,"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"]},{"name":"target-vmid","type":"integer","required":false,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"returns":{"description":"the task ID.","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 disk to another VM, you need the permissions on the target VM as well."},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/move_disk\nnodes\nmove_vm_disk\nMove volume to different storage or to a different VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to move. 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\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndelete boolean Delete the original disk after successful copy. By default the original disk is kept as unused disk.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nformat string Target Format. raw qcow2 vmdk\nstorage string Target storage.\ntarget-digest string Prevent changes if the current config file of the target VM has a different SHA1 digest. This can be used to detect concurrent modifications.\ntarget-disk string The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key. 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\ntarget-vmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/mtunnel","method":"POST","path":"/nodes/{node}/qemu/{vmid}/mtunnel","section":"nodes","summary":"mtunnel","description":"Migration tunnel endpoint - only for internal use by VM migration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"bridges","type":"string","required":false,"description":"List of network bridges to check availability. Will be checked again for actually used bridges during migration.","format":"pve-bridge-id-list"},{"name":"storages","type":"string","required":false,"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"}],"returns":{"additionalProperties":0,"properties":{"socket":{"type":"string"},"ticket":{"type":"string"},"upid":{"type":"string"}}},"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."},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/mtunnel\nnodes\nmtunnel\nMigration tunnel endpoint - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nbridges string List of network bridges to check availability. Will be checked again for actually used bridges during migration.\nstorages string List of storages to check permission and availability. Will be checked again for all actually used storages during migration.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/mtunnelwebsocket","method":"GET","path":"/nodes/{node}/qemu/{vmid}/mtunnelwebsocket","section":"nodes","summary":"mtunnelwebsocket","description":"Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"socket","type":"string","required":true,"description":"unix socket to forward to"},{"name":"ticket","type":"string","required":true,"description":"ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command"}],"returns":{"properties":{"port":{"optional":1,"type":"string"},"socket":{"optional":1,"type":"string"}},"type":"object"},"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"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/mtunnelwebsocket\nnodes\nmtunnelwebsocket\nMigration tunnel endpoint for websocket upgrade - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsocket string unix socket to forward to\nticket string ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/pending","method":"GET","path":"/nodes/{node}/qemu/{vmid}/pending","section":"nodes","summary":"vm_pending","description":"Get the virtual machine configuration with both current and pending values.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/pending\nnodes\nvm_pending\nGet the virtual machine configuration with both current and pending values.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/remote_migrate","method":"POST","path":"/nodes/{node}/qemu/{vmid}/remote_migrate","section":"nodes","summary":"remote_migrate_vm","description":"Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"target-bridge","type":"string","required":true,"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"},{"name":"target-endpoint","type":"string","required":true,"description":"Remote target endpoint","format":"proxmox-remote"},{"name":"target-storage","type":"string","required":true,"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"},{"name":"bwlimit","type":"integer","required":false,"description":"Override I/O bandwidth limit (in KiB/s).","default":"migrate limit from datacenter or storage config"},{"name":"delete","type":"boolean","required":false,"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.","default":0},{"name":"online","type":"boolean","required":false,"description":"Use online/live migration if VM is running. Ignored if VM is stopped."},{"name":"target-vmid","type":"integer","required":false,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Migrate"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/remote_migrate\nnodes\nremote_migrate_vm\nMigrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget-bridge string 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.\ntarget-endpoint string Remote target endpoint\ntarget-storage string 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.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndelete boolean 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.\nonline boolean Use online/live migration if VM is running. Ignored if VM is stopped.\ntarget-vmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/resize","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/resize","section":"nodes","summary":"resize_vm","description":"Extend volume size.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"disk","type":"string","required":true,"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"]},{"name":"size","type":"string","required":true,"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."},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications."},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/resize\nnodes\nresize_vm\nExtend volume size.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to resize. 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\nsize string 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.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/rrd","method":"GET","path":"/nodes/{node}/qemu/{vmid}/rrd","section":"nodes","summary":"rrd","description":"Read VM RRD statistics (returns PNG)","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"ds","type":"string","required":true,"description":"The list of datasources you want to display.","format":"pve-configid-list"},{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"properties":{"filename":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/rrd\nnodes\nrrd\nRead VM RRD statistics (returns PNG)\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/rrddata","method":"GET","path":"/nodes/{node}/qemu/{vmid}/rrddata","section":"nodes","summary":"rrddata","description":"Read VM RRD statistics","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/rrddata\nnodes\nrrddata\nRead VM RRD statistics\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/sendkey","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/sendkey","section":"nodes","summary":"vm_sendkey","description":"Send key event to virtual machine.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"key","type":"string","required":true,"description":"The key (qemu monitor encoding)."},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/sendkey\nnodes\nvm_sendkey\nSend key event to virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nkey string The key (qemu monitor encoding).\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/snapshot","method":"GET","path":"/nodes/{node}/qemu/{vmid}/snapshot","section":"nodes","summary":"snapshot_list","description":"List all snapshots.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/snapshot\nnodes\nsnapshot_list\nList all snapshots.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"POST /nodes/{node}/qemu/{vmid}/snapshot","method":"POST","path":"/nodes/{node}/qemu/{vmid}/snapshot","section":"nodes","summary":"snapshot","description":"Snapshot a VM.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"description","type":"string","required":false,"description":"A textual description or comment."},{"name":"vmstate","type":"boolean","required":false,"description":"Save the vmstate"}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/snapshot\nnodes\nsnapshot\nSnapshot a VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsnapname string The name of the snapshot.\ndescription string A textual description or comment.\nvmstate boolean Save the vmstate\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"DELETE /nodes/{node}/qemu/{vmid}/snapshot/{snapname}","method":"DELETE","path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}","section":"nodes","summary":"delsnapshot","description":"Delete a VM snapshot.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"For removal from config file, even if removing disk snapshots fails."}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}\nnodes\ndelsnapshot\nDelete a VM snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nforce boolean For removal from config file, even if removing disk snapshots fails.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}","method":"GET","path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}","section":"nodes","summary":"snapshot_cmd_idx","description":"snapshot_cmd_idx","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{cmd}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}\nnodes\nsnapshot_cmd_idx\nsnapshot_cmd_idx\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config","method":"GET","path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config","section":"nodes","summary":"get_snapshot_config","description":"Get snapshot configuration","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback","VM.Audit"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config\nnodes\nget_snapshot_config\nGet snapshot configuration\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config","section":"nodes","summary":"update_snapshot_config","description":"Update snapshot metadata.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"description","type":"string","required":false,"description":"A textual description or comment."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config\nnodes\nupdate_snapshot_config\nUpdate snapshot metadata.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ndescription string A textual description or comment.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"POST /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback","method":"POST","path":"/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback","section":"nodes","summary":"rollback","description":"Rollback VM state to specified snapshot.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"snapname","type":"string","required":true,"description":"The name of the snapshot.","format":"pve-configid"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"start","type":"boolean","required":false,"description":"Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)","default":0}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Snapshot","VM.Snapshot.Rollback"],"any",1]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback\nnodes\nrollback\nRollback VM state to specified snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nstart boolean Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point"} +{"id":"POST /nodes/{node}/qemu/{vmid}/spiceproxy","method":"POST","path":"/nodes/{node}/qemu/{vmid}/spiceproxy","section":"nodes","summary":"spiceproxy","description":"Returns a SPICE configuration to connect to the VM.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"proxy","type":"string","required":false,"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"}],"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"}}},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/spiceproxy\nnodes\nspiceproxy\nReturns a SPICE configuration to connect to the VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nproxy string 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).\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/status","method":"GET","path":"/nodes/{node}/qemu/{vmid}/status","section":"nodes","summary":"vmcmdidx","description":"Directory index","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/status\nnodes\nvmcmdidx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/status/current","method":"GET","path":"/nodes/{node}/qemu/{vmid}/status/current","section":"nodes","summary":"vm_status","description":"Get virtual machine status.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/status/current\nnodes\nvm_status\nGet virtual machine status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/status/reboot","method":"POST","path":"/nodes/{node}/qemu/{vmid}/status/reboot","section":"nodes","summary":"vm_reboot","description":"Reboot the VM by shutting it down, and starting it again. Applies pending changes.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"timeout","type":"integer","required":false,"description":"Wait maximal timeout seconds for the shutdown.","minimum":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/status/reboot\nnodes\nvm_reboot\nReboot the VM by shutting it down, and starting it again. Applies pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeout integer Wait maximal timeout seconds for the shutdown.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/status/reset","method":"POST","path":"/nodes/{node}/qemu/{vmid}/status/reset","section":"nodes","summary":"vm_reset","description":"Reset virtual machine.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/status/reset\nnodes\nvm_reset\nReset virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/status/resume","method":"POST","path":"/nodes/{node}/qemu/{vmid}/status/resume","section":"nodes","summary":"vm_resume","description":"Resume virtual machine.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"nocheck","type":"boolean","required":false},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/status/resume\nnodes\nvm_resume\nResume virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnocheck boolean\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/status/shutdown","method":"POST","path":"/nodes/{node}/qemu/{vmid}/status/shutdown","section":"nodes","summary":"vm_shutdown","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.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"forceStop","type":"boolean","required":false,"description":"Make sure the VM stops.","default":0},{"name":"keepActive","type":"boolean","required":false,"description":"Do not deactivate storage volumes.","default":0},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."},{"name":"timeout","type":"integer","required":false,"description":"Wait maximal timeout seconds.","minimum":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/status/shutdown\nnodes\nvm_shutdown\nShutdown 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.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforceStop boolean Make sure the VM stops.\nkeepActive boolean Do not deactivate storage volumes.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ntimeout integer Wait maximal timeout seconds.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop"} +{"id":"POST /nodes/{node}/qemu/{vmid}/status/start","method":"POST","path":"/nodes/{node}/qemu/{vmid}/status/start","section":"nodes","summary":"vm_start","description":"Start virtual machine.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"force-cpu","type":"string","required":false,"description":"Override QEMU's -cpu argument with the given string."},{"name":"machine","type":"string","required":false,"description":"Specify the QEMU machine."},{"name":"migratedfrom","type":"string","required":false,"description":"The cluster node name.","format":"pve-node"},{"name":"migration_network","type":"string","required":false,"description":"CIDR of the (sub) network that is used for migration.","format":"CIDR"},{"name":"migration_type","type":"string","required":false,"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"]},{"name":"nets-host-mtu","type":"string","required":false,"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."},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."},{"name":"stateuri","type":"string","required":false,"description":"Some command save/restore state from this location."},{"name":"targetstorage","type":"string","required":false,"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"},{"name":"timeout","type":"integer","required":false,"description":"Wait maximal timeout seconds.","default":"max(30, vm memory in GiB)","minimum":0},{"name":"with-conntrack-state","type":"boolean","required":false,"description":"Whether to migrate conntrack entries for running VMs.","default":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/status/start\nnodes\nvm_start\nStart virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce-cpu string Override QEMU's -cpu argument with the given string.\nmachine string Specify the QEMU machine.\nmigratedfrom string The cluster node name.\nmigration_network string CIDR of the (sub) network that is used for migration.\nmigration_type string Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. secure insecure\nnets-host-mtu string 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nstateuri string Some command save/restore state from this location.\ntargetstorage string 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.\ntimeout integer Wait maximal timeout seconds.\nwith-conntrack-state boolean Whether to migrate conntrack entries for running VMs.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstart\nboot\npower on"} +{"id":"POST /nodes/{node}/qemu/{vmid}/status/stop","method":"POST","path":"/nodes/{node}/qemu/{vmid}/status/stop","section":"nodes","summary":"vm_stop","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.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"keepActive","type":"boolean","required":false,"description":"Do not deactivate storage volumes.","default":0},{"name":"migratedfrom","type":"string","required":false,"description":"The cluster node name.","format":"pve-node"},{"name":"overrule-shutdown","type":"boolean","required":false,"description":"Try to abort active 'qmshutdown' tasks before stopping.","default":0},{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."},{"name":"timeout","type":"integer","required":false,"description":"Wait maximal timeout seconds.","minimum":0}],"returns":{"type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/status/stop\nnodes\nvm_stop\nStop 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.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nkeepActive boolean Do not deactivate storage volumes.\nmigratedfrom string The cluster node name.\noverrule-shutdown boolean Try to abort active 'qmshutdown' tasks before stopping.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ntimeout integer Wait maximal timeout seconds.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off"} +{"id":"POST /nodes/{node}/qemu/{vmid}/status/suspend","method":"POST","path":"/nodes/{node}/qemu/{vmid}/status/suspend","section":"nodes","summary":"vm_suspend","description":"Suspend virtual machine.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"skiplock","type":"boolean","required":false,"description":"Ignore locks - only root is allowed to use this option."},{"name":"statestorage","type":"string","required":false,"description":"The storage for the VM state","format":"pve-storage-id"},{"name":"todisk","type":"boolean","required":false,"description":"If set, suspends the VM to disk. Will be resumed on next VM start.","default":0}],"returns":{"type":"string"},"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."},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/status/suspend\nnodes\nvm_suspend\nSuspend virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nstatestorage string The storage for the VM state\ntodisk boolean If set, suspends the VM to disk. Will be resumed on next VM start.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/template","method":"POST","path":"/nodes/{node}/qemu/{vmid}/template","section":"nodes","summary":"template","description":"Create a Template.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"disk","type":"string","required":false,"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"]}],"returns":{"description":"the task ID.","type":"string"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Allocate"]],"description":"You need 'VM.Allocate' permissions on /vms/{vmid}"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/template\nnodes\ntemplate\nCreate a Template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string If you want to convert only 1 disk to base image. 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\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/termproxy","method":"POST","path":"/nodes/{node}/qemu/{vmid}/termproxy","section":"nodes","summary":"termproxy","description":"Creates a TCP proxy connections.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"serial","type":"string","required":false,"description":"opens a serial terminal (defaults to display)","enum":["serial0","serial1","serial2","serial3"]}],"returns":{"additionalProperties":0,"properties":{"port":{"type":"integer"},"ticket":{"type":"string"},"upid":{"type":"string"},"user":{"type":"string"}}},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/termproxy\nnodes\ntermproxy\nCreates a TCP proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nserial string opens a serial terminal (defaults to display) serial0 serial1 serial2 serial3\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"PUT /nodes/{node}/qemu/{vmid}/unlink","method":"PUT","path":"/nodes/{node}/qemu/{vmid}/unlink","section":"nodes","summary":"unlink","description":"Unlink/delete disk images.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"idlist","type":"string","required":true,"description":"A list of disk IDs you want to delete.","format":"pve-configid-list"},{"name":"force","type":"boolean","required":false,"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."}],"returns":{"type":"null"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Config.Disk"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/qemu/{vmid}/unlink\nnodes\nunlink\nUnlink/delete disk images.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nidlist string A list of disk IDs you want to delete.\nforce boolean 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.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"POST /nodes/{node}/qemu/{vmid}/vncproxy","method":"POST","path":"/nodes/{node}/qemu/{vmid}/vncproxy","section":"nodes","summary":"vncproxy","description":"Creates a TCP VNC proxy connections.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"generate-password","type":"boolean","required":false,"description":"Deprecated, do not use. Password is generated when required.","default":0},{"name":"websocket","type":"boolean","required":false,"description":"Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible)."}],"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"}}},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/qemu/{vmid}/vncproxy\nnodes\nvncproxy\nCreates a TCP VNC proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ngenerate-password boolean Deprecated, do not use. Password is generated when required.\nwebsocket boolean Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible).\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/qemu/{vmid}/vncwebsocket","method":"GET","path":"/nodes/{node}/qemu/{vmid}/vncwebsocket","section":"nodes","summary":"vncwebsocket","description":"Opens a websocket for VNC traffic.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vmid","type":"integer","required":true,"description":"The (unique) ID of the VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"requestParameters":[{"name":"port","type":"integer","required":true,"description":"Port number returned by previous vncproxy call.","minimum":5900,"maximum":5999},{"name":"vncticket","type":"string","required":true,"description":"Ticket from previous call to vncproxy."}],"returns":{"properties":{"port":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/vms/{vmid}",["VM.Console"]],"description":"You also need to pass a valid ticket (vncticket)."},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/qemu/{vmid}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nport integer Port number returned by previous vncproxy call.\nvncticket string Ticket from previous call to vncproxy.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id"} +{"id":"GET /nodes/{node}/query-oci-repo-tags","method":"GET","path":"/nodes/{node}/query-oci-repo-tags","section":"nodes","summary":"query_oci_repo_tags","description":"List all tags for an OCI repository reference.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"reference","type":"string","required":true,"description":"The reference to the repository to query tags from."}],"returns":{"items":{"type":"string"},"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.AccessNetwork"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/query-oci-repo-tags\nnodes\nquery_oci_repo_tags\nList all tags for an OCI repository reference.\nnode string The cluster node name.\nreference string The reference to the repository to query tags from."} +{"id":"GET /nodes/{node}/query-url-metadata","method":"GET","path":"/nodes/{node}/query-url-metadata","section":"nodes","summary":"query_url_metadata","description":"Query metadata of an URL: file size, file name and mime type.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"url","type":"string","required":true,"description":"The URL to query the metadata from."},{"name":"verify-certificates","type":"boolean","required":false,"description":"If false, no SSL/TLS certificates will be verified.","default":1}],"returns":{"properties":{"filename":{"optional":1,"type":"string"},"mimetype":{"optional":1,"type":"string"},"size":{"optional":1,"renderer":"bytes","type":"integer"}},"type":"object"},"permissions":{"check":["or",["perm","/",["Sys.Audit","Sys.Modify"]],["perm","/nodes/{node}",["Sys.AccessNetwork"]]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/query-url-metadata\nnodes\nquery_url_metadata\nQuery metadata of an URL: file size, file name and mime type.\nnode string The cluster node name.\nurl string The URL to query the metadata from.\nverify-certificates boolean If false, no SSL/TLS certificates will be verified."} +{"id":"GET /nodes/{node}/replication","method":"GET","path":"/nodes/{node}/replication","section":"nodes","summary":"status","description":"List status of all replication jobs on this node.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"guest","type":"integer","required":false,"description":"Only list replication jobs for this guest.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"returns":{"items":{"properties":{"id":{"type":"string"}},"type":"object"},"links":[{"href":"{id}","rel":"child"}],"type":"array"},"permissions":{"description":"Requires the VM.Audit permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/replication\nnodes\nstatus\nList status of all replication jobs on this node.\nnode string The cluster node name.\nguest integer Only list replication jobs for this guest."} +{"id":"GET /nodes/{node}/replication/{id}","method":"GET","path":"/nodes/{node}/replication/{id}","section":"nodes","summary":"index","description":"Directory index.","pathParameters":[{"name":"id","type":"string","required":true,"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"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/replication/{id}\nnodes\nindex\nDirectory index.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/replication/{id}/log","method":"GET","path":"/nodes/{node}/replication/{id}/log","section":"nodes","summary":"read_job_log","description":"Read replication job log.","pathParameters":[{"name":"id","type":"string","required":true,"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"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"limit","type":"integer","required":false,"minimum":0},{"name":"start","type":"integer","required":false,"minimum":0}],"returns":{"items":{"properties":{"n":{"description":"Line number","type":"integer"},"t":{"description":"Line text","type":"string"}},"type":"object"},"type":"array"},"permissions":{"description":"Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/replication/{id}/log\nnodes\nread_job_log\nRead replication job log.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name.\nlimit integer\nstart integer"} +{"id":"POST /nodes/{node}/replication/{id}/schedule_now","method":"POST","path":"/nodes/{node}/replication/{id}/schedule_now","section":"nodes","summary":"schedule_now","description":"Schedule replication job to start as soon as possible.","pathParameters":[{"name":"id","type":"string","required":true,"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"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"description":"Requires the VM.Replicate permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/replication/{id}/schedule_now\nnodes\nschedule_now\nSchedule replication job to start as soon as possible.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/replication/{id}/status","method":"GET","path":"/nodes/{node}/replication/{id}/status","section":"nodes","summary":"job_status","description":"Get replication job status.","pathParameters":[{"name":"id","type":"string","required":true,"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"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"description":"Requires the VM.Audit permission on /vms/.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/replication/{id}/status\nnodes\njob_status\nGet replication job status.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/report","method":"GET","path":"/nodes/{node}/report","section":"nodes","summary":"report","description":"Gather various systems information about a node","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/report\nnodes\nreport\nGather various systems information about a node\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/rrd","method":"GET","path":"/nodes/{node}/rrd","section":"nodes","summary":"rrd","description":"Read node RRD statistics (returns PNG)","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"ds","type":"string","required":true,"description":"The list of datasources you want to display.","format":"pve-configid-list"},{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year","decade"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"properties":{"filename":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/rrd\nnodes\nrrd\nRead node RRD statistics (returns PNG)\nnode string The cluster node name.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year decade\ncf string The RRD consolidation function AVERAGE MAX"} +{"id":"GET /nodes/{node}/rrddata","method":"GET","path":"/nodes/{node}/rrddata","section":"nodes","summary":"rrddata","description":"Read node RRD statistics","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year","decade"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/rrddata\nnodes\nrrddata\nRead node RRD statistics\nnode string The cluster node name.\ntimeframe string Specify the time frame you are interested in. hour day week month year decade\ncf string The RRD consolidation function AVERAGE MAX"} +{"id":"GET /nodes/{node}/scan","method":"GET","path":"/nodes/{node}/scan","section":"nodes","summary":"index","description":"Index of available scan methods","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{"method":{"type":"string"}},"type":"object"},"links":[{"href":"{method}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan\nnodes\nindex\nIndex of available scan methods\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/scan/cifs","method":"GET","path":"/nodes/{node}/scan/cifs","section":"nodes","summary":"cifsscan","description":"Scan remote CIFS server.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"server","type":"string","required":true,"description":"The server address (name or IP).","format":"pve-storage-server"},{"name":"domain","type":"string","required":false,"description":"SMB domain (Workgroup)."},{"name":"password","type":"string","required":false,"description":"User password."},{"name":"username","type":"string","required":false,"description":"User name."}],"returns":{"items":{"properties":{"description":{"description":"Descriptive text from server.","type":"string"},"share":{"description":"The cifs share name.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan/cifs\nnodes\ncifsscan\nScan remote CIFS server.\nnode string The cluster node name.\nserver string The server address (name or IP).\ndomain string SMB domain (Workgroup).\npassword string User password.\nusername string User name."} +{"id":"GET /nodes/{node}/scan/iscsi","method":"GET","path":"/nodes/{node}/scan/iscsi","section":"nodes","summary":"iscsiscan","description":"Scan remote iSCSI server.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"portal","type":"string","required":true,"description":"The iSCSI portal (IP or DNS name with optional port).","format":"pve-storage-portal-dns"}],"returns":{"items":{"properties":{"portal":{"description":"The iSCSI portal name.","type":"string"},"target":{"description":"The iSCSI target name.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan/iscsi\nnodes\niscsiscan\nScan remote iSCSI server.\nnode string The cluster node name.\nportal string The iSCSI portal (IP or DNS name with optional port)."} +{"id":"GET /nodes/{node}/scan/lvm","method":"GET","path":"/nodes/{node}/scan/lvm","section":"nodes","summary":"lvmscan","description":"List local LVM volume groups.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{"vg":{"description":"The LVM logical volume group name.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan/lvm\nnodes\nlvmscan\nList local LVM volume groups.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/scan/lvmthin","method":"GET","path":"/nodes/{node}/scan/lvmthin","section":"nodes","summary":"lvmthinscan","description":"List local LVM Thin Pools.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"vg","type":"string","required":true}],"returns":{"items":{"properties":{"lv":{"description":"The LVM Thin Pool name (LVM logical volume).","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan/lvmthin\nnodes\nlvmthinscan\nList local LVM Thin Pools.\nnode string The cluster node name.\nvg string"} +{"id":"GET /nodes/{node}/scan/nfs","method":"GET","path":"/nodes/{node}/scan/nfs","section":"nodes","summary":"nfsscan","description":"Scan remote NFS server.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"server","type":"string","required":true,"description":"The server address (name or IP).","format":"pve-storage-server"}],"returns":{"items":{"properties":{"options":{"description":"NFS export options.","type":"string"},"path":{"description":"The exported path.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan/nfs\nnodes\nnfsscan\nScan remote NFS server.\nnode string The cluster node name.\nserver string The server address (name or IP)."} +{"id":"GET /nodes/{node}/scan/pbs","method":"GET","path":"/nodes/{node}/scan/pbs","section":"nodes","summary":"pbsscan","description":"Scan remote Proxmox Backup Server.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"password","type":"string","required":true,"description":"User password or API token secret."},{"name":"server","type":"string","required":true,"description":"The server address (name or IP).","format":"pve-storage-server"},{"name":"username","type":"string","required":true,"description":"User-name or API token-ID."},{"name":"fingerprint","type":"string","required":false,"description":"Certificate SHA 256 fingerprint."},{"name":"port","type":"integer","required":false,"description":"Optional port.","default":8007,"minimum":1,"maximum":65535}],"returns":{"items":{"properties":{"comment":{"description":"Comment from server.","optional":1,"type":"string"},"store":{"description":"The datastore name.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan/pbs\nnodes\npbsscan\nScan remote Proxmox Backup Server.\nnode string The cluster node name.\npassword string User password or API token secret.\nserver string The server address (name or IP).\nusername string User-name or API token-ID.\nfingerprint string Certificate SHA 256 fingerprint.\nport integer Optional port."} +{"id":"GET /nodes/{node}/scan/zfs","method":"GET","path":"/nodes/{node}/scan/zfs","section":"nodes","summary":"zfsscan","description":"Scan zfs pool list on local node.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{"pool":{"description":"ZFS pool name.","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/scan/zfs\nnodes\nzfsscan\nScan zfs pool list on local node.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/sdn","method":"GET","path":"/nodes/{node}/sdn","section":"nodes","summary":"sdnindex","description":"SDN index.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn\nnodes\nsdnindex\nSDN index.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/sdn/fabrics/{fabric}","method":"GET","path":"/nodes/{node}/sdn/fabrics/{fabric}","section":"nodes","summary":"diridx","description":"Directory index for SDN fabric status.","pathParameters":[{"name":"fabric","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/fabrics/{fabric}\nnodes\ndiridx\nDirectory index for SDN fabric status.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/sdn/fabrics/{fabric}/interfaces","method":"GET","path":"/nodes/{node}/sdn/fabrics/{fabric}/interfaces","section":"nodes","summary":"interfaces","description":"Get all interfaces for a fabric.","pathParameters":[{"name":"fabric","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/fabrics/{fabric}/interfaces\nnodes\ninterfaces\nGet all interfaces for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/sdn/fabrics/{fabric}/neighbors","method":"GET","path":"/nodes/{node}/sdn/fabrics/{fabric}/neighbors","section":"nodes","summary":"neighbors","description":"Get all neighbors for a fabric.","pathParameters":[{"name":"fabric","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/fabrics/{fabric}/neighbors\nnodes\nneighbors\nGet all neighbors for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/sdn/fabrics/{fabric}/routes","method":"GET","path":"/nodes/{node}/sdn/fabrics/{fabric}/routes","section":"nodes","summary":"routes","description":"Get all routes for a fabric.","pathParameters":[{"name":"fabric","type":"string","required":true,"description":"Identifier for SDN fabrics","format":"pve-sdn-fabric-id"},{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/fabrics/{fabric}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/fabrics/{fabric}/routes\nnodes\nroutes\nGet all routes for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/sdn/vnets/{vnet}","method":"GET","path":"/nodes/{node}/sdn/vnets/{vnet}","section":"nodes","summary":"diridx","description":"diridx","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"description":"Require 'SDN.Audit' permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/vnets/{vnet}\nnodes\ndiridx\ndiridx\nnode string The cluster node name.\nvnet string The SDN vnet object identifier."} +{"id":"GET /nodes/{node}/sdn/vnets/{vnet}/mac-vrf","method":"GET","path":"/nodes/{node}/sdn/vnets/{vnet}/mac-vrf","section":"nodes","summary":"mac-vrf","description":"Get the MAC VRF for a VNet in an EVPN zone.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"vnet","type":"string","required":true,"description":"The SDN vnet object identifier."}],"requestParameters":[],"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"},"permissions":{"description":"Require 'SDN.Audit' permissions on '/sdn/zones//'","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/vnets/{vnet}/mac-vrf\nnodes\nmac-vrf\nGet the MAC VRF for a VNet in an EVPN zone.\nnode string The cluster node name.\nvnet string The SDN vnet object identifier."} +{"id":"GET /nodes/{node}/sdn/zones","method":"GET","path":"/nodes/{node}/sdn/zones","section":"nodes","summary":"index","description":"Get status for all zones.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"description":"Only list entries where you have 'SDN.Audit'","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/zones\nnodes\nindex\nGet status for all zones.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/sdn/zones/{zone}","method":"GET","path":"/nodes/{node}/sdn/zones/{zone}","section":"nodes","summary":"diridx","description":"Directory index for SDN zone status.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/zones/{zone}\nnodes\ndiridx\nDirectory index for SDN zone status.\nnode string The cluster node name.\nzone string The SDN zone object identifier."} +{"id":"GET /nodes/{node}/sdn/zones/{zone}/bridges","method":"GET","path":"/nodes/{node}/sdn/zones/{zone}/bridges","section":"nodes","summary":"bridges","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.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"zone","type":"string","required":true,"description":"zone name or \"localnetwork\""}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/zones/{zone}/bridges\nnodes\nbridges\nGet a list of all bridges (vnets) that are part of a zone, as well as the ports that are members of that bridge.\nnode string The cluster node name.\nzone string zone name or \"localnetwork\""} +{"id":"GET /nodes/{node}/sdn/zones/{zone}/content","method":"GET","path":"/nodes/{node}/sdn/zones/{zone}/content","section":"nodes","summary":"index","description":"List zone content.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"zone","type":"string","required":true,"description":"The SDN zone object identifier."}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/zones/{zone}/content\nnodes\nindex\nList zone content.\nnode string The cluster node name.\nzone string The SDN zone object identifier."} +{"id":"GET /nodes/{node}/sdn/zones/{zone}/ip-vrf","method":"GET","path":"/nodes/{node}/sdn/zones/{zone}/ip-vrf","section":"nodes","summary":"ip-vrf","description":"Get the IP VRF of an EVPN zone.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"zone","type":"string","required":true,"description":"Name of an EVPN zone."}],"requestParameters":[],"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"},"permissions":{"check":["perm","/sdn/zones/{zone}",["SDN.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/sdn/zones/{zone}/ip-vrf\nnodes\nip-vrf\nGet the IP VRF of an EVPN zone.\nnode string The cluster node name.\nzone string Name of an EVPN zone."} +{"id":"GET /nodes/{node}/services","method":"GET","path":"/nodes/{node}/services","section":"nodes","summary":"index","description":"Service list.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/services\nnodes\nindex\nService list.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/services/{service}","method":"GET","path":"/nodes/{node}/services/{service}","section":"nodes","summary":"srvcmdidx","description":"Directory index","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"service","type":"string","required":true,"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"]}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/services/{service}\nnodes\nsrvcmdidx\nDirectory index\nnode string The cluster node name.\nservice string Service ID 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"} +{"id":"POST /nodes/{node}/services/{service}/reload","method":"POST","path":"/nodes/{node}/services/{service}/reload","section":"nodes","summary":"service_reload","description":"Reload service. Falls back to restart if service cannot be reloaded.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"service","type":"string","required":true,"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"]}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/services/{service}/reload\nnodes\nservice_reload\nReload service. Falls back to restart if service cannot be reloaded.\nnode string The cluster node name.\nservice string Service ID 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"} +{"id":"POST /nodes/{node}/services/{service}/restart","method":"POST","path":"/nodes/{node}/services/{service}/restart","section":"nodes","summary":"service_restart","description":"Hard restart service. Use reload if you want to reduce interruptions.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"service","type":"string","required":true,"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"]}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/services/{service}/restart\nnodes\nservice_restart\nHard restart service. Use reload if you want to reduce interruptions.\nnode string The cluster node name.\nservice string Service ID 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"} +{"id":"POST /nodes/{node}/services/{service}/start","method":"POST","path":"/nodes/{node}/services/{service}/start","section":"nodes","summary":"service_start","description":"Start service.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"service","type":"string","required":true,"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"]}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/services/{service}/start\nnodes\nservice_start\nStart service.\nnode string The cluster node name.\nservice string Service ID 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"} +{"id":"GET /nodes/{node}/services/{service}/state","method":"GET","path":"/nodes/{node}/services/{service}/state","section":"nodes","summary":"service_state","description":"Read service properties","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"service","type":"string","required":true,"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"]}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/services/{service}/state\nnodes\nservice_state\nRead service properties\nnode string The cluster node name.\nservice string Service ID 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"} +{"id":"POST /nodes/{node}/services/{service}/stop","method":"POST","path":"/nodes/{node}/services/{service}/stop","section":"nodes","summary":"service_stop","description":"Stop service.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"service","type":"string","required":true,"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"]}],"requestParameters":[],"returns":{"type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/services/{service}/stop\nnodes\nservice_stop\nStop service.\nnode string The cluster node name.\nservice string Service ID 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"} +{"id":"POST /nodes/{node}/spiceshell","method":"POST","path":"/nodes/{node}/spiceshell","section":"nodes","summary":"spiceshell","description":"Creates a SPICE shell.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"cmd","type":"string","required":false,"description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","login","upgrade"],"default":"login"},{"name":"cmd-opts","type":"string","required":false,"description":"Add parameters to a command. Encoded as null terminated strings.","default":""},{"name":"proxy","type":"string","required":false,"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"}],"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"}}},"permissions":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/spiceshell\nnodes\nspiceshell\nCreates a SPICE shell.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings.\nproxy string 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)."} +{"id":"POST /nodes/{node}/startall","method":"POST","path":"/nodes/{node}/startall","section":"nodes","summary":"startall","description":"Start all VMs and containers located on this node (by default only those with onboot=1).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Issue start command even if virtual guest have 'onboot' not set or set to off.","default":"off"},{"name":"max-workers","type":"integer","required":false,"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.","minimum":1,"maximum":64},{"name":"vms","type":"string","required":false,"description":"Only consider guests from this comma separated list of VMIDs.","format":"pve-vmid-list"}],"returns":{"type":"string"},"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","user":"all"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/startall\nnodes\nstartall\nStart all VMs and containers located on this node (by default only those with onboot=1).\nnode string The cluster node name.\nforce boolean Issue start command even if virtual guest have 'onboot' not set or set to off.\nmax-workers integer 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.\nvms string Only consider guests from this comma separated list of VMIDs."} +{"id":"GET /nodes/{node}/status","method":"GET","path":"/nodes/{node}/status","section":"nodes","summary":"status","description":"Read node status","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/status\nnodes\nstatus\nRead node status\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/status","method":"POST","path":"/nodes/{node}/status","section":"nodes","summary":"node_cmd","description":"Reboot or shutdown a node.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"command","type":"string","required":true,"description":"Specify the command.","enum":["reboot","shutdown"]}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/status\nnodes\nnode_cmd\nReboot or shutdown a node.\nnode string The cluster node name.\ncommand string Specify the command. reboot shutdown"} +{"id":"POST /nodes/{node}/stopall","method":"POST","path":"/nodes/{node}/stopall","section":"nodes","summary":"stopall","description":"Stop all VMs and Containers.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"force-stop","type":"boolean","required":false,"description":"Force a hard-stop after the timeout.","default":1},{"name":"max-workers","type":"integer","required":false,"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.","minimum":1,"maximum":64},{"name":"timeout","type":"integer","required":false,"description":"Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.","default":180,"minimum":0,"maximum":7200},{"name":"vms","type":"string","required":false,"description":"Only consider Guests with these IDs.","format":"pve-vmid-list"}],"returns":{"type":"string"},"permissions":{"description":"The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.","user":"all"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/stopall\nnodes\nstopall\nStop all VMs and Containers.\nnode string The cluster node name.\nforce-stop boolean Force a hard-stop after the timeout.\nmax-workers integer 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.\ntimeout integer Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.\nvms string Only consider Guests with these IDs."} +{"id":"GET /nodes/{node}/storage","method":"GET","path":"/nodes/{node}/storage","section":"nodes","summary":"index","description":"Get status for all datastores.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"content","type":"string","required":false,"description":"Only list stores which support this content type.","format":"pve-storage-content-list"},{"name":"enabled","type":"boolean","required":false,"description":"Only list stores which are enabled (not disabled in config).","default":0},{"name":"format","type":"boolean","required":false,"description":"Include information about formats","default":0},{"name":"storage","type":"string","required":false,"description":"Only list status for specified storage","format":"pve-storage-id"},{"name":"target","type":"string","required":false,"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"}],"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"},"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage\nnodes\nindex\nGet status for all datastores.\nnode string The cluster node name.\ncontent string Only list stores which support this content type.\nenabled boolean Only list stores which are enabled (not disabled in config).\nformat boolean Include information about formats\nstorage string Only list status for specified storage\ntarget string If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}","method":"GET","path":"/nodes/{node}/storage/{storage}","section":"nodes","summary":"diridx","description":"diridx","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[],"returns":{"items":{"properties":{"subdir":{"type":"string"}},"type":"object"},"links":[{"href":"{subdir}","rel":"child"}],"type":"array"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}\nnodes\ndiridx\ndiridx\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/content","method":"GET","path":"/nodes/{node}/storage/{storage}/content","section":"nodes","summary":"index","description":"List storage content.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"content","type":"string","required":false,"description":"Only list content of this type.","format":"pve-storage-content"},{"name":"vmid","type":"integer","required":false,"description":"Only list images for this VM","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"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"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/content\nnodes\nindex\nList storage content.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Only list content of this type.\nvmid integer Only list images for this VM\ndatastore\nvolume storage"} +{"id":"POST /nodes/{node}/storage/{storage}/content","method":"POST","path":"/nodes/{node}/storage/{storage}/content","section":"nodes","summary":"create","description":"Allocate disk images.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"filename","type":"string","required":true,"description":"The name of the file to create."},{"name":"size","type":"string","required":true,"description":"Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)"},{"name":"vmid","type":"integer","required":true,"description":"Specify owner VM","minimum":100,"maximum":999999999,"format":"pve-vmid"},{"name":"format","type":"string","required":false,"description":"Format of the image.","enum":["raw","qcow2","subvol","vmdk"]}],"returns":{"description":"Volume identifier","type":"string"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.AllocateSpace"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/storage/{storage}/content\nnodes\ncreate\nAllocate disk images.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilename string The name of the file to create.\nsize string Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)\nvmid integer Specify owner VM\nformat string Format of the image. raw qcow2 subvol vmdk\ndatastore\nvolume storage"} +{"id":"DELETE /nodes/{node}/storage/{storage}/content/{volume}","method":"DELETE","path":"/nodes/{node}/storage/{storage}/content/{volume}","section":"nodes","summary":"delete","description":"Delete volume","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"volume","type":"string","required":true,"description":"Volume identifier"},{"name":"storage","type":"string","required":false,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"delay","type":"integer","required":false,"description":"Time to wait for the task to finish. We return 'null' if the task finish within that time.","minimum":1,"maximum":30}],"returns":{"optional":1,"type":"string"},"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"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ndelete\nDelete volume\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\ndelay integer Time to wait for the task to finish. We return 'null' if the task finish within that time.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/content/{volume}","method":"GET","path":"/nodes/{node}/storage/{storage}/content/{volume}","section":"nodes","summary":"info","description":"Get volume attributes","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"volume","type":"string","required":true,"description":"Volume identifier"},{"name":"storage","type":"string","required":false,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[],"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"},"permissions":{"description":"You need read access for the volume.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ninfo\nGet volume attributes\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\ndatastore\nvolume storage"} +{"id":"POST /nodes/{node}/storage/{storage}/content/{volume}","method":"POST","path":"/nodes/{node}/storage/{storage}/content/{volume}","section":"nodes","summary":"copy","description":"Copy a volume. This is experimental code - do not use.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"volume","type":"string","required":true,"description":"Source volume identifier"},{"name":"storage","type":"string","required":false,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"target","type":"string","required":true,"description":"Target volume identifier"},{"name":"target_node","type":"string","required":false,"description":"Target node. Default is local node.","format":"pve-node"}],"returns":{"type":"string"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ncopy\nCopy a volume. This is experimental code - do not use.\nnode string The cluster node name.\nvolume string Source volume identifier\nstorage string The storage identifier.\ntarget string Target volume identifier\ntarget_node string Target node. Default is local node.\ndatastore\nvolume storage"} +{"id":"PUT /nodes/{node}/storage/{storage}/content/{volume}","method":"PUT","path":"/nodes/{node}/storage/{storage}/content/{volume}","section":"nodes","summary":"updateattributes","description":"Update volume attributes","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"volume","type":"string","required":true,"description":"Volume identifier"},{"name":"storage","type":"string","required":false,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"notes","type":"string","required":false,"description":"The new notes."},{"name":"protected","type":"boolean","required":false,"description":"Protection status. Currently only supported for backups."}],"returns":{"type":"null"},"permissions":{"description":"You need read access for the volume.","user":"all"},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\nupdateattributes\nUpdate volume attributes\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\nnotes string The new notes.\nprotected boolean Protection status. Currently only supported for backups.\ndatastore\nvolume storage"} +{"id":"POST /nodes/{node}/storage/{storage}/download-url","method":"POST","path":"/nodes/{node}/storage/{storage}/download-url","section":"nodes","summary":"download_url","description":"Download templates, ISO images, OVAs and VM images by using an URL.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"content","type":"string","required":true,"description":"Content type.","enum":["iso","vztmpl","import"],"format":"pve-storage-content"},{"name":"filename","type":"string","required":true,"description":"The name of the file to create. Caution: This will be normalized!"},{"name":"url","type":"string","required":true,"description":"The URL to download the file from."},{"name":"checksum","type":"string","required":false,"description":"The expected checksum of the file."},{"name":"checksum-algorithm","type":"string","required":false,"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"]},{"name":"compression","type":"string","required":false,"description":"Decompress the downloaded file using the specified compression algorithm."},{"name":"verify-certificates","type":"boolean","required":false,"description":"If false, no SSL/TLS certificates will be verified.","default":1}],"returns":{"type":"string"},"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."},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/storage/{storage}/download-url\nnodes\ndownload_url\nDownload templates, ISO images, OVAs and VM images by using an URL.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Content type. iso vztmpl import\nfilename string The name of the file to create. Caution: This will be normalized!\nurl string The URL to download the file from.\nchecksum string The expected checksum of the file.\nchecksum-algorithm string The algorithm to calculate the checksum of the file. md5 sha1 sha224 sha256 sha384 sha512\ncompression string Decompress the downloaded file using the specified compression algorithm.\nverify-certificates boolean If false, no SSL/TLS certificates will be verified.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/file-restore/download","method":"GET","path":"/nodes/{node}/storage/{storage}/file-restore/download","section":"nodes","summary":"download","description":"Extract a file or directory (as zip archive) from a PBS backup.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"filepath","type":"string","required":true,"description":"base64-path to the directory or file to download."},{"name":"volume","type":"string","required":true,"description":"Backup volume ID or name. Currently only PBS snapshots are supported."},{"name":"tar","type":"boolean","required":false,"description":"Download dirs as 'tar.zst' instead of 'zip'.","default":0}],"returns":{"type":"any"},"permissions":{"description":"You need read access for the volume.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/file-restore/download\nnodes\ndownload\nExtract a file or directory (as zip archive) from a PBS backup.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilepath string base64-path to the directory or file to download.\nvolume string Backup volume ID or name. Currently only PBS snapshots are supported.\ntar boolean Download dirs as 'tar.zst' instead of 'zip'.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/file-restore/list","method":"GET","path":"/nodes/{node}/storage/{storage}/file-restore/list","section":"nodes","summary":"list","description":"List files and directories for single file restore under the given path.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"filepath","type":"string","required":true,"description":"base64-path to the directory or file being listed, or \"/\"."},{"name":"volume","type":"string","required":true,"description":"Backup volume ID or name. Currently only PBS snapshots are supported."}],"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"},"permissions":{"description":"You need read access for the volume.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/file-restore/list\nnodes\nlist\nList files and directories for single file restore under the given path.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilepath string base64-path to the directory or file being listed, or \"/\".\nvolume string Backup volume ID or name. Currently only PBS snapshots are supported.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/identity","method":"GET","path":"/nodes/{node}/storage/{storage}/identity","section":"nodes","summary":"identity","description":"Return identity information for this storage instance.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/identity\nnodes\nidentity\nReturn identity information for this storage instance.\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/import-metadata","method":"GET","path":"/nodes/{node}/storage/{storage}/import-metadata","section":"nodes","summary":"get_import_metadata","description":"Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"volume","type":"string","required":true,"description":"Volume identifier for the guest archive/entry."}],"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"},"permissions":{"description":"You need read access for the volume.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/import-metadata\nnodes\nget_import_metadata\nGet the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM\nnode string The cluster node name.\nstorage string The storage identifier.\nvolume string Volume identifier for the guest archive/entry.\ndatastore\nvolume storage"} +{"id":"POST /nodes/{node}/storage/{storage}/oci-registry-pull","method":"POST","path":"/nodes/{node}/storage/{storage}/oci-registry-pull","section":"nodes","summary":"oci_registry_pull","description":"Pull an OCI image from a registry.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"reference","type":"string","required":true,"description":"The reference to the OCI image to download."},{"name":"filename","type":"string","required":false,"description":"Custom destination file name of the OCI image. Caution: This will be normalized!"}],"returns":{"type":"string"},"permissions":{"check":["and",["perm","/storage/{storage}",["Datastore.AllocateTemplate"]],["perm","/nodes/{node}",["Sys.AccessNetwork"]]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/storage/{storage}/oci-registry-pull\nnodes\noci_registry_pull\nPull an OCI image from a registry.\nnode string The cluster node name.\nstorage string The storage identifier.\nreference string The reference to the OCI image to download.\nfilename string Custom destination file name of the OCI image. Caution: This will be normalized!\ndatastore\nvolume storage"} +{"id":"DELETE /nodes/{node}/storage/{storage}/prunebackups","method":"DELETE","path":"/nodes/{node}/storage/{storage}/prunebackups","section":"nodes","summary":"delete","description":"Prune backups. Only those using the standard naming scheme are considered.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"prune-backups","type":"string","required":false,"description":"Use these retention options instead of those from the storage configuration.","format":"prune-backups"},{"name":"type","type":"string","required":false,"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"]},{"name":"vmid","type":"integer","required":false,"description":"Only prune backups for this VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"returns":{"type":"string"},"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"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/storage/{storage}/prunebackups\nnodes\ndelete\nPrune backups. Only those using the standard naming scheme are considered.\nnode string The cluster node name.\nstorage string The storage identifier.\nprune-backups string Use these retention options instead of those from the storage configuration.\ntype string Either 'qemu' or 'lxc'. Only consider backups for guests of this type. qemu lxc\nvmid integer Only prune backups for this VM.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/prunebackups","method":"GET","path":"/nodes/{node}/storage/{storage}/prunebackups","section":"nodes","summary":"dryrun","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.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"prune-backups","type":"string","required":false,"description":"Use these retention options instead of those from the storage configuration.","format":"prune-backups"},{"name":"type","type":"string","required":false,"description":"Either 'qemu' or 'lxc'. Only consider backups for guests of this type.","enum":["qemu","lxc"]},{"name":"vmid","type":"integer","required":false,"description":"Only consider backups for this guest.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"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"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/prunebackups\nnodes\ndryrun\nGet 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.\nnode string The cluster node name.\nstorage string The storage identifier.\nprune-backups string Use these retention options instead of those from the storage configuration.\ntype string Either 'qemu' or 'lxc'. Only consider backups for guests of this type. qemu lxc\nvmid integer Only consider backups for this guest.\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/rrd","method":"GET","path":"/nodes/{node}/storage/{storage}/rrd","section":"nodes","summary":"rrd","description":"Read storage RRD statistics (returns PNG).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"ds","type":"string","required":true,"description":"The list of datasources you want to display.","format":"pve-configid-list"},{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"properties":{"filename":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/rrd\nnodes\nrrd\nRead storage RRD statistics (returns PNG).\nnode string The cluster node name.\nstorage string The storage identifier.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/rrddata","method":"GET","path":"/nodes/{node}/storage/{storage}/rrddata","section":"nodes","summary":"rrddata","description":"Read storage RRD statistics.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"timeframe","type":"string","required":true,"description":"Specify the time frame you are interested in.","enum":["hour","day","week","month","year"]},{"name":"cf","type":"string","required":false,"description":"The RRD consolidation function","enum":["AVERAGE","MAX"]}],"returns":{"items":{"properties":{},"type":"object"},"type":"array"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/rrddata\nnodes\nrrddata\nRead storage RRD statistics.\nnode string The cluster node name.\nstorage string The storage identifier.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ndatastore\nvolume storage"} +{"id":"GET /nodes/{node}/storage/{storage}/status","method":"GET","path":"/nodes/{node}/storage/{storage}/status","section":"nodes","summary":"read_status","description":"Read storage status.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Audit","Datastore.AllocateSpace"],"any",1]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/storage/{storage}/status\nnodes\nread_status\nRead storage status.\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage"} +{"id":"POST /nodes/{node}/storage/{storage}/upload","method":"POST","path":"/nodes/{node}/storage/{storage}/upload","section":"nodes","summary":"upload","description":"Upload templates, ISO images, OVAs and VM images.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"content","type":"string","required":true,"description":"Content type.","enum":["iso","vztmpl","import"],"format":"pve-storage-content"},{"name":"filename","type":"string","required":true,"description":"The name of the file to create. Caution: This will be normalized!"},{"name":"checksum","type":"string","required":false,"description":"The expected checksum of the file."},{"name":"checksum-algorithm","type":"string","required":false,"description":"The algorithm to calculate the checksum of the file.","enum":["md5","sha1","sha224","sha256","sha384","sha512"]},{"name":"tmpfilename","type":"string","required":false,"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."}],"returns":{"type":"string"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.AllocateTemplate"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/storage/{storage}/upload\nnodes\nupload\nUpload templates, ISO images, OVAs and VM images.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Content type. iso vztmpl import\nfilename string The name of the file to create. Caution: This will be normalized!\nchecksum string The expected checksum of the file.\nchecksum-algorithm string The algorithm to calculate the checksum of the file. md5 sha1 sha224 sha256 sha384 sha512\ntmpfilename string 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.\ndatastore\nvolume storage"} +{"id":"DELETE /nodes/{node}/subscription","method":"DELETE","path":"/nodes/{node}/subscription","section":"nodes","summary":"delete","description":"Delete subscription key of this node.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/subscription\nnodes\ndelete\nDelete subscription key of this node.\nnode string The cluster node name."} +{"id":"GET /nodes/{node}/subscription","method":"GET","path":"/nodes/{node}/subscription","section":"nodes","summary":"get","description":"Read subscription info.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/subscription\nnodes\nget\nRead subscription info.\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/subscription","method":"POST","path":"/nodes/{node}/subscription","section":"nodes","summary":"update","description":"Update subscription info.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"force","type":"boolean","required":false,"description":"Always connect to server, even if local cache is still valid.","default":0}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/subscription\nnodes\nupdate\nUpdate subscription info.\nnode string The cluster node name.\nforce boolean Always connect to server, even if local cache is still valid."} +{"id":"PUT /nodes/{node}/subscription","method":"PUT","path":"/nodes/{node}/subscription","section":"nodes","summary":"set","description":"Set subscription key.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"key","type":"string","required":true,"description":"Proxmox VE subscription key"}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/subscription\nnodes\nset\nSet subscription key.\nnode string The cluster node name.\nkey string Proxmox VE subscription key"} +{"id":"POST /nodes/{node}/suspendall","method":"POST","path":"/nodes/{node}/suspendall","section":"nodes","summary":"suspendall","description":"Suspend all VMs.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"max-workers","type":"integer","required":false,"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.","minimum":1,"maximum":64},{"name":"vms","type":"string","required":false,"description":"Only consider Guests with these IDs.","format":"pve-vmid-list"}],"returns":{"type":"string"},"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"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/suspendall\nnodes\nsuspendall\nSuspend all VMs.\nnode string The cluster node name.\nmax-workers integer 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.\nvms string Only consider Guests with these IDs."} +{"id":"GET /nodes/{node}/syslog","method":"GET","path":"/nodes/{node}/syslog","section":"nodes","summary":"syslog","description":"Read system log","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"limit","type":"integer","required":false,"minimum":0},{"name":"service","type":"string","required":false,"description":"Service ID"},{"name":"since","type":"string","required":false,"description":"Display all log since this date-time string."},{"name":"start","type":"integer","required":false,"minimum":0},{"name":"until","type":"string","required":false,"description":"Display all log until this date-time string."}],"returns":{"items":{"properties":{"n":{"description":"Line number","type":"integer"},"t":{"description":"Line text","type":"string"}},"type":"object"},"type":"array"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Syslog"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/syslog\nnodes\nsyslog\nRead system log\nnode string The cluster node name.\nlimit integer\nservice string Service ID\nsince string Display all log since this date-time string.\nstart integer\nuntil string Display all log until this date-time string."} +{"id":"GET /nodes/{node}/tasks","method":"GET","path":"/nodes/{node}/tasks","section":"nodes","summary":"node_tasks","description":"Read task list for one node (finished tasks).","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"errors","type":"boolean","required":false,"description":"Only list tasks with a status of ERROR.","default":0},{"name":"limit","type":"integer","required":false,"description":"Only list this number of tasks.","default":50,"minimum":0},{"name":"since","type":"integer","required":false,"description":"Only list tasks since this UNIX epoch."},{"name":"source","type":"string","required":false,"description":"List archived, active or all tasks.","enum":["archive","active","all"],"default":"archive"},{"name":"start","type":"integer","required":false,"description":"List tasks beginning from this offset.","default":0,"minimum":0},{"name":"statusfilter","type":"string","required":false,"description":"List of Task States that should be returned.","format":"pve-task-status-type-list"},{"name":"typefilter","type":"string","required":false,"description":"Only list tasks of this type (e.g., vzstart, vzdump)."},{"name":"until","type":"integer","required":false,"description":"Only list tasks until this UNIX epoch."},{"name":"userfilter","type":"string","required":false,"description":"Only list tasks from this user."},{"name":"vmid","type":"integer","required":false,"description":"Only list tasks for this VM.","minimum":100,"maximum":999999999,"format":"pve-vmid"}],"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"},"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"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/tasks\nnodes\nnode_tasks\nRead task list for one node (finished tasks).\nnode string The cluster node name.\nerrors boolean Only list tasks with a status of ERROR.\nlimit integer Only list this number of tasks.\nsince integer Only list tasks since this UNIX epoch.\nsource string List archived, active or all tasks. archive active all\nstart integer List tasks beginning from this offset.\nstatusfilter string List of Task States that should be returned.\ntypefilter string Only list tasks of this type (e.g., vzstart, vzdump).\nuntil integer Only list tasks until this UNIX epoch.\nuserfilter string Only list tasks from this user.\nvmid integer Only list tasks for this VM."} +{"id":"DELETE /nodes/{node}/tasks/{upid}","method":"DELETE","path":"/nodes/{node}/tasks/{upid}","section":"nodes","summary":"stop_task","description":"Stop a task.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"upid","type":"string","required":true}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"description":"The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.","user":"all"},"raw":{"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"}},"searchText":"DELETE\n/nodes/{node}/tasks/{upid}\nnodes\nstop_task\nStop a task.\nnode string The cluster node name.\nupid string"} +{"id":"GET /nodes/{node}/tasks/{upid}","method":"GET","path":"/nodes/{node}/tasks/{upid}","section":"nodes","summary":"upid_index","description":"upid_index","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"upid","type":"string","required":true}],"requestParameters":[],"returns":{"items":{"properties":{},"type":"object"},"links":[{"href":"{name}","rel":"child"}],"type":"array"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/tasks/{upid}\nnodes\nupid_index\nupid_index\nnode string The cluster node name.\nupid string"} +{"id":"GET /nodes/{node}/tasks/{upid}/log","method":"GET","path":"/nodes/{node}/tasks/{upid}/log","section":"nodes","summary":"read_task_log","description":"Read task log.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"upid","type":"string","required":true,"description":"The task's unique ID."}],"requestParameters":[{"name":"download","type":"boolean","required":false,"description":"Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters"},{"name":"limit","type":"integer","required":false,"description":"The number of lines to read from the tasklog.","default":50,"minimum":0},{"name":"start","type":"integer","required":false,"description":"Start at this line when reading the tasklog","default":0,"minimum":0}],"returns":{"items":{"properties":{"n":{"description":"Line number","type":"integer"},"t":{"description":"Line text","type":"string"}},"type":"object"},"type":"array"},"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/tasks/{upid}/log\nnodes\nread_task_log\nRead task log.\nnode string The cluster node name.\nupid string The task's unique ID.\ndownload boolean Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters\nlimit integer The number of lines to read from the tasklog.\nstart integer Start at this line when reading the tasklog"} +{"id":"GET /nodes/{node}/tasks/{upid}/status","method":"GET","path":"/nodes/{node}/tasks/{upid}/status","section":"nodes","summary":"read_task_status","description":"Read task status.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"},{"name":"upid","type":"string","required":true,"description":"The task's unique ID."}],"requestParameters":[],"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"},"permissions":{"description":"The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/tasks/{upid}/status\nnodes\nread_task_status\nRead task status.\nnode string The cluster node name.\nupid string The task's unique ID."} +{"id":"POST /nodes/{node}/termproxy","method":"POST","path":"/nodes/{node}/termproxy","section":"nodes","summary":"termproxy","description":"Creates a VNC Shell proxy.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"cmd","type":"string","required":false,"description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","login","upgrade"],"default":"login"},{"name":"cmd-opts","type":"string","required":false,"description":"Add parameters to a command. Encoded as null terminated strings.","default":""}],"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"}}},"permissions":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/termproxy\nnodes\ntermproxy\nCreates a VNC Shell proxy.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings."} +{"id":"GET /nodes/{node}/time","method":"GET","path":"/nodes/{node}/time","section":"nodes","summary":"time","description":"Read server time and time zone settings.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Audit"]]},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/time\nnodes\ntime\nRead server time and time zone settings.\nnode string The cluster node name."} +{"id":"PUT /nodes/{node}/time","method":"PUT","path":"/nodes/{node}/time","section":"nodes","summary":"set_timezone","description":"Set time zone.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"timezone","type":"string","required":true,"description":"Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names."}],"returns":{"type":"null"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Modify"]]},"raw":{"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"}},"searchText":"PUT\n/nodes/{node}/time\nnodes\nset_timezone\nSet time zone.\nnode string The cluster node name.\ntimezone string Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names."} +{"id":"GET /nodes/{node}/version","method":"GET","path":"/nodes/{node}/version","section":"nodes","summary":"version","description":"API version details","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/version\nnodes\nversion\nAPI version details\nnode string The cluster node name."} +{"id":"POST /nodes/{node}/vncshell","method":"POST","path":"/nodes/{node}/vncshell","section":"nodes","summary":"vncshell","description":"Creates a VNC Shell proxy.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"cmd","type":"string","required":false,"description":"Run specific command or default to login (requires 'root@pam')","enum":["ceph_install","login","upgrade"],"default":"login"},{"name":"cmd-opts","type":"string","required":false,"description":"Add parameters to a command. Encoded as null terminated strings.","default":""},{"name":"height","type":"integer","required":false,"description":"sets the height of the console in pixels.","minimum":16,"maximum":2160},{"name":"websocket","type":"boolean","required":false,"description":"use websocket instead of standard vnc."},{"name":"width","type":"integer","required":false,"description":"sets the width of the console in pixels.","minimum":16,"maximum":4096}],"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"}}},"permissions":{"check":["perm","/nodes/{node}",["Sys.Console"]]},"raw":{"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"}}}},"searchText":"POST\n/nodes/{node}/vncshell\nnodes\nvncshell\nCreates a VNC Shell proxy.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings.\nheight integer sets the height of the console in pixels.\nwebsocket boolean use websocket instead of standard vnc.\nwidth integer sets the width of the console in pixels."} +{"id":"GET /nodes/{node}/vncwebsocket","method":"GET","path":"/nodes/{node}/vncwebsocket","section":"nodes","summary":"vncwebsocket","description":"Opens a websocket for VNC traffic.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"port","type":"integer","required":true,"description":"Port number returned by previous 'vncshell' call.","minimum":5900,"maximum":5999},{"name":"vncticket","type":"string","required":true,"description":"Ticket from previous call to 'vncshell'."}],"returns":{"properties":{"port":{"type":"string"}},"type":"object"},"permissions":{"check":["perm","/nodes/{node}",["Sys.Console"]],"description":"You also need to pass a valid ticket (vncticket)."},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nport integer Port number returned by previous 'vncshell' call.\nvncticket string Ticket from previous call to 'vncshell'."} +{"id":"POST /nodes/{node}/vzdump","method":"POST","path":"/nodes/{node}/vzdump","section":"nodes","summary":"vzdump","description":"Create backup.","pathParameters":[{"name":"node","type":"string","required":false,"description":"Only run if executed on this node.","format":"pve-node"}],"requestParameters":[{"name":"all","type":"boolean","required":false,"description":"Backup all known guest systems on this host.","default":0},{"name":"bwlimit","type":"integer","required":false,"description":"Limit I/O bandwidth (in KiB/s).","default":0,"minimum":0},{"name":"compress","type":"string","required":false,"description":"Compress dump file.","enum":["0","1","gzip","lzo","zstd"],"default":"0"},{"name":"dumpdir","type":"string","required":false,"description":"Store resulting files to specified directory."},{"name":"exclude","type":"string","required":false,"description":"Exclude specified guest systems (assumes --all)","format":"pve-vmid-list"},{"name":"exclude-path","type":"array","required":false,"description":"Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory."},{"name":"fleecing","type":"string","required":false,"description":"Options for backup fleecing (VM only).","format":"backup-fleecing"},{"name":"ionice","type":"integer","required":false,"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.","default":7,"minimum":0,"maximum":8},{"name":"job-id","type":"string","required":false,"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."},{"name":"lockwait","type":"integer","required":false,"description":"Maximal time to wait for the global lock (minutes).","default":180,"minimum":0},{"name":"mailnotification","type":"string","required":false,"description":"Deprecated: use notification targets/matchers instead. Specify when to send a notification mail","enum":["always","failure"],"default":"always"},{"name":"mailto","type":"string","required":false,"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"},{"name":"mode","type":"string","required":false,"description":"Backup mode.","enum":["snapshot","suspend","stop"],"default":"snapshot"},{"name":"notes-template","type":"string","required":false,"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."},{"name":"notification-mode","type":"string","required":false,"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"],"default":"auto"},{"name":"pbs-change-detection-mode","type":"string","required":false,"description":"PBS mode used to detect file changes and switch encoding format for container backups.","enum":["legacy","data","metadata"]},{"name":"performance","type":"string","required":false,"description":"Other performance-related settings.","format":"backup-performance"},{"name":"pigz","type":"integer","required":false,"description":"Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.","default":0},{"name":"pool","type":"string","required":false,"description":"Backup all known guest systems included in the specified pool."},{"name":"protected","type":"boolean","required":false,"description":"If true, mark backup(s) as protected."},{"name":"prune-backups","type":"string","required":false,"description":"Use these retention options instead of those from the storage configuration.","default":"keep-all=1","format":"prune-backups"},{"name":"quiet","type":"boolean","required":false,"description":"Be quiet.","default":0},{"name":"remove","type":"boolean","required":false,"description":"Prune older backups according to 'prune-backups'.","default":1},{"name":"script","type":"string","required":false,"description":"Use specified hook script."},{"name":"stdexcludes","type":"boolean","required":false,"description":"Exclude temporary files and logs.","default":1},{"name":"stdout","type":"boolean","required":false,"description":"Write tar to stdout, not to a file."},{"name":"stop","type":"boolean","required":false,"description":"Stop running backup jobs on this host.","default":0},{"name":"stopwait","type":"integer","required":false,"description":"Maximal time to wait until a guest system is stopped (minutes).","default":10,"minimum":0},{"name":"storage","type":"string","required":false,"description":"Store resulting file to this storage.","format":"pve-storage-id"},{"name":"tmpdir","type":"string","required":false,"description":"Store temporary files to specified directory."},{"name":"vmid","type":"string","required":false,"description":"The ID of the guest system you want to backup.","format":"pve-vmid-list"},{"name":"zstd","type":"integer","required":false,"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.","default":1}],"returns":{"type":"string"},"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"},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/vzdump\nnodes\nvzdump\nCreate backup.\nnode string Only run if executed on this node.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndumpdir string Store resulting files to specified directory.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nionice integer 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.\njob-id string 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nscript string Use specified hook script.\nstdexcludes boolean Exclude temporary files and logs.\nstdout boolean Write tar to stdout, not to a file.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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."} +{"id":"GET /nodes/{node}/vzdump/defaults","method":"GET","path":"/nodes/{node}/vzdump/defaults","section":"nodes","summary":"defaults","description":"Get the currently configured vzdump defaults.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"storage","type":"string","required":false,"description":"The storage identifier.","format":"pve-storage-id"}],"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"},"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"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/vzdump/defaults\nnodes\ndefaults\nGet the currently configured vzdump defaults.\nnode string The cluster node name.\nstorage string The storage identifier."} +{"id":"GET /nodes/{node}/vzdump/extractconfig","method":"GET","path":"/nodes/{node}/vzdump/extractconfig","section":"nodes","summary":"extractconfig","description":"Extract configuration from vzdump backup archive.","pathParameters":[{"name":"node","type":"string","required":true,"description":"The cluster node name.","format":"pve-node"}],"requestParameters":[{"name":"volume","type":"string","required":true,"description":"Volume identifier"}],"returns":{"type":"string"},"permissions":{"description":"The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.","user":"all"},"raw":{"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"}},"searchText":"GET\n/nodes/{node}/vzdump/extractconfig\nnodes\nextractconfig\nExtract configuration from vzdump backup archive.\nnode string The cluster node name.\nvolume string Volume identifier"} +{"id":"POST /nodes/{node}/wakeonlan","method":"POST","path":"/nodes/{node}/wakeonlan","section":"nodes","summary":"wakeonlan","description":"Try to wake a node via 'wake on LAN' network packet.","pathParameters":[{"name":"node","type":"string","required":true,"description":"target node for wake on LAN packet","format":"pve-node"}],"requestParameters":[],"returns":{"description":"MAC address used to assemble the WoL magic packet.","format":"mac-addr","type":"string"},"permissions":{"check":["perm","/nodes/{node}",["Sys.PowerMgmt"]]},"raw":{"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"}},"searchText":"POST\n/nodes/{node}/wakeonlan\nnodes\nwakeonlan\nTry to wake a node via 'wake on LAN' network packet.\nnode string target node for wake on LAN packet"} +{"id":"DELETE /pools","method":"DELETE","path":"/pools","section":"pools","summary":"delete_pool","description":"Delete pool.","pathParameters":[],"requestParameters":[{"name":"poolid","type":"string","required":true,"format":"pve-poolid"}],"returns":{"type":"null"},"permissions":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]],"description":"You can only delete empty pools (no members)."},"raw":{"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"}},"searchText":"DELETE\n/pools\npools\ndelete_pool\nDelete pool.\npoolid string"} +{"id":"GET /pools","method":"GET","path":"/pools","section":"pools","summary":"index","description":"List pools or get pool configuration.","pathParameters":[],"requestParameters":[{"name":"poolid","type":"string","required":false,"format":"pve-poolid"},{"name":"type","type":"string","required":false,"enum":["qemu","lxc","storage"]}],"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"},"permissions":{"description":"List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}","user":"all"},"raw":{"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"}},"searchText":"GET\n/pools\npools\nindex\nList pools or get pool configuration.\npoolid string\ntype string qemu lxc storage"} +{"id":"POST /pools","method":"POST","path":"/pools","section":"pools","summary":"create_pool","description":"Create new pool.","pathParameters":[],"requestParameters":[{"name":"poolid","type":"string","required":true,"format":"pve-poolid"},{"name":"comment","type":"string","required":false}],"returns":{"type":"null"},"permissions":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/pools\npools\ncreate_pool\nCreate new pool.\npoolid string\ncomment string"} +{"id":"PUT /pools","method":"PUT","path":"/pools","section":"pools","summary":"update_pool","description":"Update pool.","pathParameters":[],"requestParameters":[{"name":"poolid","type":"string","required":true,"format":"pve-poolid"},{"name":"allow-move","type":"boolean","required":false,"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.","default":0},{"name":"comment","type":"string","required":false},{"name":"delete","type":"boolean","required":false,"description":"Remove the passed VMIDs and/or storage IDs instead of adding them.","default":0},{"name":"storage","type":"string","required":false,"description":"List of storage IDs to add or remove from this pool.","format":"pve-storage-id-list"},{"name":"vms","type":"string","required":false,"description":"List of guest VMIDs to add or remove from this pool.","format":"pve-vmid-list"}],"returns":{"type":"null"},"permissions":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]],"description":"You also need the right to modify permissions on any object you add/delete."},"raw":{"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"}},"searchText":"PUT\n/pools\npools\nupdate_pool\nUpdate pool.\npoolid string\nallow-move boolean Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.\ncomment string\ndelete boolean Remove the passed VMIDs and/or storage IDs instead of adding them.\nstorage string List of storage IDs to add or remove from this pool.\nvms string List of guest VMIDs to add or remove from this pool."} +{"id":"DELETE /pools/{poolid}","method":"DELETE","path":"/pools/{poolid}","section":"pools","summary":"delete_pool_deprecated","description":"Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').","pathParameters":[{"name":"poolid","type":"string","required":true,"format":"pve-poolid"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]],"description":"You can only delete empty pools (no members)."},"raw":{"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"}},"searchText":"DELETE\n/pools/{poolid}\npools\ndelete_pool_deprecated\nDelete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').\npoolid string"} +{"id":"GET /pools/{poolid}","method":"GET","path":"/pools/{poolid}","section":"pools","summary":"read_pool","description":"Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').","pathParameters":[{"name":"poolid","type":"string","required":true,"format":"pve-poolid"}],"requestParameters":[{"name":"type","type":"string","required":false,"enum":["qemu","lxc","storage"]}],"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"},"permissions":{"check":["perm","/pool/{poolid}",["Pool.Audit"]]},"raw":{"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"}},"searchText":"GET\n/pools/{poolid}\npools\nread_pool\nGet pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').\npoolid string\ntype string qemu lxc storage"} +{"id":"PUT /pools/{poolid}","method":"PUT","path":"/pools/{poolid}","section":"pools","summary":"update_pool_deprecated","description":"Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).","pathParameters":[{"name":"poolid","type":"string","required":true,"format":"pve-poolid"}],"requestParameters":[{"name":"allow-move","type":"boolean","required":false,"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.","default":0},{"name":"comment","type":"string","required":false},{"name":"delete","type":"boolean","required":false,"description":"Remove the passed VMIDs and/or storage IDs instead of adding them.","default":0},{"name":"storage","type":"string","required":false,"description":"List of storage IDs to add or remove from this pool.","format":"pve-storage-id-list"},{"name":"vms","type":"string","required":false,"description":"List of guest VMIDs to add or remove from this pool.","format":"pve-vmid-list"}],"returns":{"type":"null"},"permissions":{"check":["perm","/pool/{poolid}",["Pool.Allocate"]],"description":"You also need the right to modify permissions on any object you add/delete."},"raw":{"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"}},"searchText":"PUT\n/pools/{poolid}\npools\nupdate_pool_deprecated\nUpdate pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).\npoolid string\nallow-move boolean Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.\ncomment string\ndelete boolean Remove the passed VMIDs and/or storage IDs instead of adding them.\nstorage string List of storage IDs to add or remove from this pool.\nvms string List of guest VMIDs to add or remove from this pool."} +{"id":"GET /storage","method":"GET","path":"/storage","section":"storage","summary":"index","description":"Storage index.","pathParameters":[],"requestParameters":[{"name":"type","type":"string","required":false,"description":"Only list storage of specific type","enum":["btrfs","cephfs","cifs","dir","esxi","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"]}],"returns":{"items":{"properties":{"storage":{"type":"string"}},"type":"object"},"links":[{"href":"{storage}","rel":"child"}],"type":"array"},"permissions":{"description":"Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'","user":"all"},"raw":{"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"}},"searchText":"GET\n/storage\nstorage\nindex\nStorage index.\ntype string Only list storage of specific type btrfs cephfs cifs dir esxi iscsi iscsidirect lvm lvmthin nfs pbs rbd zfs zfspool\ndatastore\nvolume storage"} +{"id":"POST /storage","method":"POST","path":"/storage","section":"storage","summary":"create","description":"Create a new storage.","pathParameters":[],"requestParameters":[{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"},{"name":"type","type":"string","required":true,"description":"Storage type.","enum":["btrfs","cephfs","cifs","dir","esxi","iscsi","iscsidirect","lvm","lvmthin","nfs","pbs","rbd","zfs","zfspool"]},{"name":"authsupported","type":"string","required":false,"description":"Authsupported."},{"name":"base","type":"string","required":false,"description":"Base volume. This volume is automatically activated.","format":"pve-volume-id"},{"name":"blocksize","type":"string","required":false,"description":"ZFS block size","format":"pve-storage-zfs-blocksize"},{"name":"bwlimit","type":"string","required":false,"description":"Set I/O bandwidth limit for various operations (in KiB/s)."},{"name":"comstar_hg","type":"string","required":false,"description":"host group for comstar views"},{"name":"comstar_tg","type":"string","required":false,"description":"target group for comstar views"},{"name":"content","type":"string","required":false,"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.","format":"pve-storage-content-list"},{"name":"content-dirs","type":"string","required":false,"description":"Overrides for default content type directories.","format":"pve-dir-override-list"},{"name":"create-base-path","type":"boolean","required":false,"description":"Create the base directory if it doesn't exist.","default":"yes"},{"name":"create-subdirs","type":"boolean","required":false,"description":"Populate the directory with the default structure.","default":"yes"},{"name":"data-pool","type":"string","required":false,"description":"Data Pool (for erasure coding only)"},{"name":"datastore","type":"string","required":false,"description":"Proxmox Backup Server datastore name."},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable the storage."},{"name":"domain","type":"string","required":false,"description":"CIFS domain."},{"name":"encryption-key","type":"string","required":false,"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase."},{"name":"export","type":"string","required":false,"description":"NFS export path.","format":"pve-storage-path"},{"name":"fingerprint","type":"string","required":false,"description":"Certificate SHA 256 fingerprint."},{"name":"format","type":"string","required":false,"description":"Default image format.","enum":["raw","qcow2","subvol","vmdk"]},{"name":"fs-name","type":"string","required":false,"description":"The Ceph filesystem name.","format":"pve-configid"},{"name":"fuse","type":"boolean","required":false,"description":"Mount CephFS through FUSE."},{"name":"is_mountpoint","type":"string","required":false,"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.","default":"no"},{"name":"iscsiprovider","type":"string","required":false,"description":"iscsi provider"},{"name":"keyring","type":"string","required":false,"description":"Client keyring contents (for external clusters)."},{"name":"krbd","type":"boolean","required":false,"description":"Always access rbd through krbd kernel module.","default":0},{"name":"lio_tpg","type":"string","required":false,"description":"target portal group for Linux LIO targets"},{"name":"master-pubkey","type":"string","required":false,"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."},{"name":"max-protected-backups","type":"integer","required":false,"description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","minimum":-1},{"name":"mkdir","type":"boolean","required":false,"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.","default":"yes"},{"name":"monhost","type":"string","required":false,"description":"IP addresses of monitors (for external clusters).","format":"pve-storage-portal-dns-list"},{"name":"mountpoint","type":"string","required":false,"description":"mount point","format":"pve-storage-path"},{"name":"namespace","type":"string","required":false,"description":"Namespace."},{"name":"nocow","type":"boolean","required":false,"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.","default":0},{"name":"nodes","type":"string","required":false,"description":"List of nodes for which the storage configuration applies.","format":"pve-node-list"},{"name":"nowritecache","type":"boolean","required":false,"description":"disable write caching on the target"},{"name":"options","type":"string","required":false,"description":"NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')","format":"pve-storage-options"},{"name":"password","type":"string","required":false,"description":"Password for accessing the share/datastore."},{"name":"path","type":"string","required":false,"description":"File system path.","format":"pve-storage-path"},{"name":"pool","type":"string","required":false,"description":"Pool."},{"name":"port","type":"integer","required":false,"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.","minimum":1,"maximum":65535},{"name":"portal","type":"string","required":false,"description":"iSCSI portal (IP or DNS name with optional port).","format":"pve-storage-portal-dns"},{"name":"preallocation","type":"string","required":false,"description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"default":"metadata"},{"name":"prune-backups","type":"string","required":false,"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"},{"name":"saferemove","type":"boolean","required":false,"description":"Zero-out data when removing LVs."},{"name":"saferemove_throughput","type":"string","required":false,"description":"Wipe throughput (cstream -t parameter value)."},{"name":"saferemove-stepsize","type":"integer","required":false,"description":"Wipe step size in MiB. It will be capped to the maximum supported by the storage.","enum":["1","2","4","8","16","32"],"default":32},{"name":"server","type":"string","required":false,"description":"Server IP or DNS name.","format":"pve-storage-server"},{"name":"share","type":"string","required":false,"description":"CIFS share."},{"name":"shared","type":"boolean","required":false,"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!"},{"name":"skip-cert-verification","type":"boolean","required":false,"description":"Disable TLS certificate verification, only enable on fully trusted networks!","default":"false"},{"name":"smbversion","type":"string","required":false,"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"],"default":"default"},{"name":"snapshot-as-volume-chain","type":"boolean","required":false,"description":"Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.","default":0},{"name":"sparse","type":"boolean","required":false,"description":"use sparse volumes"},{"name":"subdir","type":"string","required":false,"description":"Subdir to mount.","format":"pve-storage-path"},{"name":"tagged_only","type":"boolean","required":false,"description":"Only list logical volumes tagged with 'pve-vm-ID'."},{"name":"target","type":"string","required":false,"description":"iSCSI target."},{"name":"thinpool","type":"string","required":false,"description":"LVM thin pool LV name.","format":"pve-storage-vgname"},{"name":"username","type":"string","required":false,"description":"RBD Id."},{"name":"vgname","type":"string","required":false,"description":"Volume group name.","format":"pve-storage-vgname"},{"name":"zfs-base-path","type":"string","required":false,"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"}],"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"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"POST\n/storage\nstorage\ncreate\nCreate a new storage.\nstorage string The storage identifier.\ntype string Storage type. btrfs cephfs cifs dir esxi iscsi iscsidirect lvm lvmthin nfs pbs rbd zfs zfspool\nauthsupported string Authsupported.\nbase string Base volume. This volume is automatically activated.\nblocksize string ZFS block size\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\ncomstar_hg string host group for comstar views\ncomstar_tg string target group for comstar views\ncontent string Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\ncontent-dirs string Overrides for default content type directories.\ncreate-base-path boolean Create the base directory if it doesn't exist.\ncreate-subdirs boolean Populate the directory with the default structure.\ndata-pool string Data Pool (for erasure coding only)\ndatastore string Proxmox Backup Server datastore name.\ndisable boolean Flag to disable the storage.\ndomain string CIFS domain.\nencryption-key string Encryption key. Use 'autogen' to generate one automatically without passphrase.\nexport string NFS export path.\nfingerprint string Certificate SHA 256 fingerprint.\nformat string Default image format. raw qcow2 subvol vmdk\nfs-name string The Ceph filesystem name.\nfuse boolean Mount CephFS through FUSE.\nis_mountpoint string 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.\niscsiprovider string iscsi provider\nkeyring string Client keyring contents (for external clusters).\nkrbd boolean Always access rbd through krbd kernel module.\nlio_tpg string target portal group for Linux LIO targets\nmaster-pubkey string Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.\nmax-protected-backups integer Maximal number of protected backups per guest. Use '-1' for unlimited.\nmkdir boolean 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.\nmonhost string IP addresses of monitors (for external clusters).\nmountpoint string mount point\nnamespace string Namespace.\nnocow boolean 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.\nnodes string List of nodes for which the storage configuration applies.\nnowritecache boolean disable write caching on the target\noptions string NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')\npassword string Password for accessing the share/datastore.\npath string File system path.\npool string Pool.\nport integer 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.\nportal string iSCSI portal (IP or DNS name with optional port).\npreallocation string Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. off metadata falloc full\nprune-backups string 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.\nsaferemove boolean Zero-out data when removing LVs.\nsaferemove_throughput string Wipe throughput (cstream -t parameter value).\nsaferemove-stepsize integer Wipe step size in MiB. It will be capped to the maximum supported by the storage. 1 2 4 8 16 32\nserver string Server IP or DNS name.\nshare string CIFS share.\nshared boolean 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!\nskip-cert-verification boolean Disable TLS certificate verification, only enable on fully trusted networks!\nsmbversion string SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. default 2.0 2.1 3 3.0 3.11\nsnapshot-as-volume-chain boolean Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.\nsparse boolean use sparse volumes\nsubdir string Subdir to mount.\ntagged_only boolean Only list logical volumes tagged with 'pve-vm-ID'.\ntarget string iSCSI target.\nthinpool string LVM thin pool LV name.\nusername string RBD Id.\nvgname string Volume group name.\nzfs-base-path string Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.\ndatastore\nvolume storage"} +{"id":"DELETE /storage/{storage}","method":"DELETE","path":"/storage/{storage}","section":"storage","summary":"delete","description":"Delete storage configuration.","pathParameters":[{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[],"returns":{"type":"null"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"DELETE\n/storage/{storage}\nstorage\ndelete\nDelete storage configuration.\nstorage string The storage identifier.\ndatastore\nvolume storage"} +{"id":"GET /storage/{storage}","method":"GET","path":"/storage/{storage}","section":"storage","summary":"read","description":"Read storage configuration.","pathParameters":[{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[],"returns":{"type":"object"},"permissions":{"check":["perm","/storage/{storage}",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"GET\n/storage/{storage}\nstorage\nread\nRead storage configuration.\nstorage string The storage identifier.\ndatastore\nvolume storage"} +{"id":"PUT /storage/{storage}","method":"PUT","path":"/storage/{storage}","section":"storage","summary":"update","description":"Update storage configuration.","pathParameters":[{"name":"storage","type":"string","required":true,"description":"The storage identifier.","format":"pve-storage-id"}],"requestParameters":[{"name":"blocksize","type":"string","required":false,"description":"ZFS block size","format":"pve-storage-zfs-blocksize"},{"name":"bwlimit","type":"string","required":false,"description":"Set I/O bandwidth limit for various operations (in KiB/s)."},{"name":"comstar_hg","type":"string","required":false,"description":"host group for comstar views"},{"name":"comstar_tg","type":"string","required":false,"description":"target group for comstar views"},{"name":"content","type":"string","required":false,"description":"Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.","format":"pve-storage-content-list"},{"name":"content-dirs","type":"string","required":false,"description":"Overrides for default content type directories.","format":"pve-dir-override-list"},{"name":"create-base-path","type":"boolean","required":false,"description":"Create the base directory if it doesn't exist.","default":"yes"},{"name":"create-subdirs","type":"boolean","required":false,"description":"Populate the directory with the default structure.","default":"yes"},{"name":"data-pool","type":"string","required":false,"description":"Data Pool (for erasure coding only)"},{"name":"delete","type":"string","required":false,"description":"A list of settings you want to delete.","format":"pve-configid-list"},{"name":"digest","type":"string","required":false,"description":"Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications."},{"name":"disable","type":"boolean","required":false,"description":"Flag to disable the storage."},{"name":"domain","type":"string","required":false,"description":"CIFS domain."},{"name":"encryption-key","type":"string","required":false,"description":"Encryption key. Use 'autogen' to generate one automatically without passphrase."},{"name":"fingerprint","type":"string","required":false,"description":"Certificate SHA 256 fingerprint."},{"name":"format","type":"string","required":false,"description":"Default image format.","enum":["raw","qcow2","subvol","vmdk"]},{"name":"fs-name","type":"string","required":false,"description":"The Ceph filesystem name.","format":"pve-configid"},{"name":"fuse","type":"boolean","required":false,"description":"Mount CephFS through FUSE."},{"name":"is_mountpoint","type":"string","required":false,"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.","default":"no"},{"name":"keyring","type":"string","required":false,"description":"Client keyring contents (for external clusters)."},{"name":"krbd","type":"boolean","required":false,"description":"Always access rbd through krbd kernel module.","default":0},{"name":"lio_tpg","type":"string","required":false,"description":"target portal group for Linux LIO targets"},{"name":"master-pubkey","type":"string","required":false,"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."},{"name":"max-protected-backups","type":"integer","required":false,"description":"Maximal number of protected backups per guest. Use '-1' for unlimited.","default":"Unlimited for users with Datastore.Allocate privilege, 5 for other users","minimum":-1},{"name":"mkdir","type":"boolean","required":false,"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.","default":"yes"},{"name":"monhost","type":"string","required":false,"description":"IP addresses of monitors (for external clusters).","format":"pve-storage-portal-dns-list"},{"name":"mountpoint","type":"string","required":false,"description":"mount point","format":"pve-storage-path"},{"name":"namespace","type":"string","required":false,"description":"Namespace."},{"name":"nocow","type":"boolean","required":false,"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.","default":0},{"name":"nodes","type":"string","required":false,"description":"List of nodes for which the storage configuration applies.","format":"pve-node-list"},{"name":"nowritecache","type":"boolean","required":false,"description":"disable write caching on the target"},{"name":"options","type":"string","required":false,"description":"NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')","format":"pve-storage-options"},{"name":"password","type":"string","required":false,"description":"Password for accessing the share/datastore."},{"name":"pool","type":"string","required":false,"description":"Pool."},{"name":"port","type":"integer","required":false,"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.","minimum":1,"maximum":65535},{"name":"preallocation","type":"string","required":false,"description":"Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off.","enum":["off","metadata","falloc","full"],"default":"metadata"},{"name":"prune-backups","type":"string","required":false,"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"},{"name":"saferemove","type":"boolean","required":false,"description":"Zero-out data when removing LVs."},{"name":"saferemove_throughput","type":"string","required":false,"description":"Wipe throughput (cstream -t parameter value)."},{"name":"saferemove-stepsize","type":"integer","required":false,"description":"Wipe step size in MiB. It will be capped to the maximum supported by the storage.","enum":["1","2","4","8","16","32"],"default":32},{"name":"server","type":"string","required":false,"description":"Server IP or DNS name.","format":"pve-storage-server"},{"name":"shared","type":"boolean","required":false,"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!"},{"name":"skip-cert-verification","type":"boolean","required":false,"description":"Disable TLS certificate verification, only enable on fully trusted networks!","default":"false"},{"name":"smbversion","type":"string","required":false,"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"],"default":"default"},{"name":"snapshot-as-volume-chain","type":"boolean","required":false,"description":"Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.","default":0},{"name":"sparse","type":"boolean","required":false,"description":"use sparse volumes"},{"name":"subdir","type":"string","required":false,"description":"Subdir to mount.","format":"pve-storage-path"},{"name":"tagged_only","type":"boolean","required":false,"description":"Only list logical volumes tagged with 'pve-vm-ID'."},{"name":"username","type":"string","required":false,"description":"RBD Id."},{"name":"zfs-base-path","type":"string","required":false,"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"}],"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"},"permissions":{"check":["perm","/storage",["Datastore.Allocate"]]},"raw":{"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"}},"searchText":"PUT\n/storage/{storage}\nstorage\nupdate\nUpdate storage configuration.\nstorage string The storage identifier.\nblocksize string ZFS block size\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\ncomstar_hg string host group for comstar views\ncomstar_tg string target group for comstar views\ncontent string Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\ncontent-dirs string Overrides for default content type directories.\ncreate-base-path boolean Create the base directory if it doesn't exist.\ncreate-subdirs boolean Populate the directory with the default structure.\ndata-pool string Data Pool (for erasure coding only)\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the storage.\ndomain string CIFS domain.\nencryption-key string Encryption key. Use 'autogen' to generate one automatically without passphrase.\nfingerprint string Certificate SHA 256 fingerprint.\nformat string Default image format. raw qcow2 subvol vmdk\nfs-name string The Ceph filesystem name.\nfuse boolean Mount CephFS through FUSE.\nis_mountpoint string 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.\nkeyring string Client keyring contents (for external clusters).\nkrbd boolean Always access rbd through krbd kernel module.\nlio_tpg string target portal group for Linux LIO targets\nmaster-pubkey string Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.\nmax-protected-backups integer Maximal number of protected backups per guest. Use '-1' for unlimited.\nmkdir boolean 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.\nmonhost string IP addresses of monitors (for external clusters).\nmountpoint string mount point\nnamespace string Namespace.\nnocow boolean 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.\nnodes string List of nodes for which the storage configuration applies.\nnowritecache boolean disable write caching on the target\noptions string NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')\npassword string Password for accessing the share/datastore.\npool string Pool.\nport integer 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.\npreallocation string Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. off metadata falloc full\nprune-backups string 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.\nsaferemove boolean Zero-out data when removing LVs.\nsaferemove_throughput string Wipe throughput (cstream -t parameter value).\nsaferemove-stepsize integer Wipe step size in MiB. It will be capped to the maximum supported by the storage. 1 2 4 8 16 32\nserver string Server IP or DNS name.\nshared boolean 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!\nskip-cert-verification boolean Disable TLS certificate verification, only enable on fully trusted networks!\nsmbversion string SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. default 2.0 2.1 3 3.0 3.11\nsnapshot-as-volume-chain boolean Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.\nsparse boolean use sparse volumes\nsubdir string Subdir to mount.\ntagged_only boolean Only list logical volumes tagged with 'pve-vm-ID'.\nusername string RBD Id.\nzfs-base-path string Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.\ndatastore\nvolume storage"} +{"id":"GET /version","method":"GET","path":"/version","section":"version","summary":"version","description":"API version details, including some parts of the global datacenter config.","pathParameters":[],"requestParameters":[],"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"},"permissions":{"user":"all"},"raw":{"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"}},"searchText":"GET\n/version\nversion\nversion\nAPI version details, including some parts of the global datacenter config."} diff --git a/docs/pve-api/llms-full.txt b/docs/pve-api/llms-full.txt new file mode 100644 index 00000000000..1ff0890a8d2 --- /dev/null +++ b/docs/pve-api/llms-full.txt @@ -0,0 +1,120830 @@ +# Proxmox VE API Documentation + +Static documentation generated from Proxmox VE `apidoc.js`. + +| Method | Path | Summary | +|---|---|---| +| GET | `/access` | [index](endpoints/GET_access.md) | +| GET | `/access/acl` | [read_acl](endpoints/GET_access_acl.md) | +| PUT | `/access/acl` | [update_acl](endpoints/PUT_access_acl.md) | +| GET | `/access/domains` | [index](endpoints/GET_access_domains.md) | +| POST | `/access/domains` | [create](endpoints/POST_access_domains.md) | +| DELETE | `/access/domains/{realm}` | [delete](endpoints/DELETE_access_domains_realm.md) | +| GET | `/access/domains/{realm}` | [read](endpoints/GET_access_domains_realm.md) | +| PUT | `/access/domains/{realm}` | [update](endpoints/PUT_access_domains_realm.md) | +| POST | `/access/domains/{realm}/sync` | [sync](endpoints/POST_access_domains_realm_sync.md) | +| GET | `/access/groups` | [index](endpoints/GET_access_groups.md) | +| POST | `/access/groups` | [create_group](endpoints/POST_access_groups.md) | +| DELETE | `/access/groups/{groupid}` | [delete_group](endpoints/DELETE_access_groups_groupid.md) | +| GET | `/access/groups/{groupid}` | [read_group](endpoints/GET_access_groups_groupid.md) | +| PUT | `/access/groups/{groupid}` | [update_group](endpoints/PUT_access_groups_groupid.md) | +| GET | `/access/openid` | [index](endpoints/GET_access_openid.md) | +| POST | `/access/openid/auth-url` | [auth_url](endpoints/POST_access_openid_auth_url.md) | +| POST | `/access/openid/login` | [login](endpoints/POST_access_openid_login.md) | +| PUT | `/access/password` | [change_password](endpoints/PUT_access_password.md) | +| GET | `/access/permissions` | [permissions](endpoints/GET_access_permissions.md) | +| GET | `/access/roles` | [index](endpoints/GET_access_roles.md) | +| POST | `/access/roles` | [create_role](endpoints/POST_access_roles.md) | +| DELETE | `/access/roles/{roleid}` | [delete_role](endpoints/DELETE_access_roles_roleid.md) | +| GET | `/access/roles/{roleid}` | [read_role](endpoints/GET_access_roles_roleid.md) | +| PUT | `/access/roles/{roleid}` | [update_role](endpoints/PUT_access_roles_roleid.md) | +| GET | `/access/tfa` | [list_tfa](endpoints/GET_access_tfa.md) | +| GET | `/access/tfa/{userid}` | [list_user_tfa](endpoints/GET_access_tfa_userid.md) | +| POST | `/access/tfa/{userid}` | [add_tfa_entry](endpoints/POST_access_tfa_userid.md) | +| DELETE | `/access/tfa/{userid}/{id}` | [delete_tfa](endpoints/DELETE_access_tfa_userid_id.md) | +| GET | `/access/tfa/{userid}/{id}` | [get_tfa_entry](endpoints/GET_access_tfa_userid_id.md) | +| PUT | `/access/tfa/{userid}/{id}` | [update_tfa_entry](endpoints/PUT_access_tfa_userid_id.md) | +| GET | `/access/ticket` | [get_ticket](endpoints/GET_access_ticket.md) | +| POST | `/access/ticket` | [create_ticket](endpoints/POST_access_ticket.md) | +| GET | `/access/users` | [index](endpoints/GET_access_users.md) | +| POST | `/access/users` | [create_user](endpoints/POST_access_users.md) | +| DELETE | `/access/users/{userid}` | [delete_user](endpoints/DELETE_access_users_userid.md) | +| GET | `/access/users/{userid}` | [read_user](endpoints/GET_access_users_userid.md) | +| PUT | `/access/users/{userid}` | [update_user](endpoints/PUT_access_users_userid.md) | +| GET | `/access/users/{userid}/tfa` | [read_user_tfa_type](endpoints/GET_access_users_userid_tfa.md) | +| GET | `/access/users/{userid}/token` | [token_index](endpoints/GET_access_users_userid_token.md) | +| DELETE | `/access/users/{userid}/token/{tokenid}` | [remove_token](endpoints/DELETE_access_users_userid_token_tokenid.md) | +| GET | `/access/users/{userid}/token/{tokenid}` | [read_token](endpoints/GET_access_users_userid_token_tokenid.md) | +| POST | `/access/users/{userid}/token/{tokenid}` | [generate_token](endpoints/POST_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/token/{tokenid}` | [update_token_info](endpoints/PUT_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/unlock-tfa` | [unlock_tfa](endpoints/PUT_access_users_userid_unlock_tfa.md) | +| POST | `/access/vncticket` | [verify_vnc_ticket](endpoints/POST_access_vncticket.md) | +| GET | `/cluster` | [index](endpoints/GET_cluster.md) | +| GET | `/cluster/acme` | [index](endpoints/GET_cluster_acme.md) | +| GET | `/cluster/acme/account` | [account_index](endpoints/GET_cluster_acme_account.md) | +| POST | `/cluster/acme/account` | [register_account](endpoints/POST_cluster_acme_account.md) | +| DELETE | `/cluster/acme/account/{name}` | [deactivate_account](endpoints/DELETE_cluster_acme_account_name.md) | +| GET | `/cluster/acme/account/{name}` | [get_account](endpoints/GET_cluster_acme_account_name.md) | +| PUT | `/cluster/acme/account/{name}` | [update_account](endpoints/PUT_cluster_acme_account_name.md) | +| GET | `/cluster/acme/challenge-schema` | [challengeschema](endpoints/GET_cluster_acme_challenge_schema.md) | +| GET | `/cluster/acme/directories` | [get_directories](endpoints/GET_cluster_acme_directories.md) | +| GET | `/cluster/acme/meta` | [get_meta](endpoints/GET_cluster_acme_meta.md) | +| GET | `/cluster/acme/plugins` | [index](endpoints/GET_cluster_acme_plugins.md) | +| POST | `/cluster/acme/plugins` | [add_plugin](endpoints/POST_cluster_acme_plugins.md) | +| DELETE | `/cluster/acme/plugins/{id}` | [delete_plugin](endpoints/DELETE_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/plugins/{id}` | [get_plugin_config](endpoints/GET_cluster_acme_plugins_id.md) | +| PUT | `/cluster/acme/plugins/{id}` | [update_plugin](endpoints/PUT_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/tos` | [get_tos](endpoints/GET_cluster_acme_tos.md) | +| GET | `/cluster/backup` | [index](endpoints/GET_cluster_backup.md) | +| POST | `/cluster/backup` | [create_job](endpoints/POST_cluster_backup.md) | +| GET | `/cluster/backup-info` | [index](endpoints/GET_cluster_backup_info.md) | +| GET | `/cluster/backup-info/not-backed-up` | [get_guests_not_in_backup](endpoints/GET_cluster_backup_info_not_backed_up.md) | +| DELETE | `/cluster/backup/{id}` | [delete_job](endpoints/DELETE_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}` | [read_job](endpoints/GET_cluster_backup_id.md) | +| PUT | `/cluster/backup/{id}` | [update_job](endpoints/PUT_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}/included_volumes` | [get_volume_backup_included](endpoints/GET_cluster_backup_id_included_volumes.md) | +| GET | `/cluster/bulk-action` | [index](endpoints/GET_cluster_bulk_action.md) | +| GET | `/cluster/bulk-action/guest` | [index](endpoints/GET_cluster_bulk_action_guest.md) | +| POST | `/cluster/bulk-action/guest/migrate` | [migrate](endpoints/POST_cluster_bulk_action_guest_migrate.md) | +| POST | `/cluster/bulk-action/guest/shutdown` | [shutdown](endpoints/POST_cluster_bulk_action_guest_shutdown.md) | +| POST | `/cluster/bulk-action/guest/start` | [start](endpoints/POST_cluster_bulk_action_guest_start.md) | +| POST | `/cluster/bulk-action/guest/suspend` | [suspend](endpoints/POST_cluster_bulk_action_guest_suspend.md) | +| GET | `/cluster/ceph` | [cephindex](endpoints/GET_cluster_ceph.md) | +| GET | `/cluster/ceph/flags` | [get_all_flags](endpoints/GET_cluster_ceph_flags.md) | +| PUT | `/cluster/ceph/flags` | [set_flags](endpoints/PUT_cluster_ceph_flags.md) | +| GET | `/cluster/ceph/flags/{flag}` | [get_flag](endpoints/GET_cluster_ceph_flags_flag.md) | +| PUT | `/cluster/ceph/flags/{flag}` | [update_flag](endpoints/PUT_cluster_ceph_flags_flag.md) | +| GET | `/cluster/ceph/metadata` | [metadata](endpoints/GET_cluster_ceph_metadata.md) | +| GET | `/cluster/ceph/status` | [status](endpoints/GET_cluster_ceph_status.md) | +| GET | `/cluster/config` | [index](endpoints/GET_cluster_config.md) | +| POST | `/cluster/config` | [create](endpoints/POST_cluster_config.md) | +| GET | `/cluster/config/apiversion` | [join_api_version](endpoints/GET_cluster_config_apiversion.md) | +| GET | `/cluster/config/join` | [join_info](endpoints/GET_cluster_config_join.md) | +| POST | `/cluster/config/join` | [join](endpoints/POST_cluster_config_join.md) | +| GET | `/cluster/config/nodes` | [nodes](endpoints/GET_cluster_config_nodes.md) | +| DELETE | `/cluster/config/nodes/{node}` | [delnode](endpoints/DELETE_cluster_config_nodes_node.md) | +| POST | `/cluster/config/nodes/{node}` | [addnode](endpoints/POST_cluster_config_nodes_node.md) | +| GET | `/cluster/config/qdevice` | [status](endpoints/GET_cluster_config_qdevice.md) | +| GET | `/cluster/config/totem` | [totem](endpoints/GET_cluster_config_totem.md) | +| GET | `/cluster/firewall` | [index](endpoints/GET_cluster_firewall.md) | +| GET | `/cluster/firewall/aliases` | [get_aliases](endpoints/GET_cluster_firewall_aliases.md) | +| POST | `/cluster/firewall/aliases` | [create_alias](endpoints/POST_cluster_firewall_aliases.md) | +| DELETE | `/cluster/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/aliases/{name}` | [read_alias](endpoints/GET_cluster_firewall_aliases_name.md) | +| PUT | `/cluster/firewall/aliases/{name}` | [update_alias](endpoints/PUT_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/groups` | [list_security_groups](endpoints/GET_cluster_firewall_groups.md) | +| POST | `/cluster/firewall/groups` | [create_security_group](endpoints/POST_cluster_firewall_groups.md) | +| DELETE | `/cluster/firewall/groups/{group}` | [delete_security_group](endpoints/DELETE_cluster_firewall_groups_group.md) | +| GET | `/cluster/firewall/groups/{group}` | [get_rules](endpoints/GET_cluster_firewall_groups_group.md) | +| POST | `/cluster/firewall/groups/{group}` | [create_rule](endpoints/POST_cluster_firewall_groups_group.md) | +| DELETE | `/cluster/firewall/groups/{group}/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/groups/{group}/{pos}` | [get_rule](endpoints/GET_cluster_firewall_groups_group_pos.md) | +| PUT | `/cluster/firewall/groups/{group}/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/ipset` | [ipset_index](endpoints/GET_cluster_firewall_ipset.md) | +| POST | `/cluster/firewall/ipset` | [create_ipset](endpoints/POST_cluster_firewall_ipset.md) | +| DELETE | `/cluster/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_cluster_firewall_ipset_name.md) | +| GET | `/cluster/firewall/ipset/{name}` | [get_ipset](endpoints/GET_cluster_firewall_ipset_name.md) | +| POST | `/cluster/firewall/ipset/{name}` | [create_ip](endpoints/POST_cluster_firewall_ipset_name.md) | +| DELETE | `/cluster/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_cluster_firewall_ipset_name_cidr.md) | +| PUT | `/cluster/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/macros` | [get_macros](endpoints/GET_cluster_firewall_macros.md) | +| GET | `/cluster/firewall/options` | [get_options](endpoints/GET_cluster_firewall_options.md) | +| PUT | `/cluster/firewall/options` | [set_options](endpoints/PUT_cluster_firewall_options.md) | +| GET | `/cluster/firewall/refs` | [refs](endpoints/GET_cluster_firewall_refs.md) | +| GET | `/cluster/firewall/rules` | [get_rules](endpoints/GET_cluster_firewall_rules.md) | +| POST | `/cluster/firewall/rules` | [create_rule](endpoints/POST_cluster_firewall_rules.md) | +| DELETE | `/cluster/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_rules_pos.md) | +| GET | `/cluster/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_firewall_rules_pos.md) | +| PUT | `/cluster/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_rules_pos.md) | +| GET | `/cluster/ha` | [index](endpoints/GET_cluster_ha.md) | +| GET | `/cluster/ha/groups` | [index](endpoints/GET_cluster_ha_groups.md) | +| POST | `/cluster/ha/groups` | [create](endpoints/POST_cluster_ha_groups.md) | +| DELETE | `/cluster/ha/groups/{group}` | [delete](endpoints/DELETE_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/groups/{group}` | [read](endpoints/GET_cluster_ha_groups_group.md) | +| PUT | `/cluster/ha/groups/{group}` | [update](endpoints/PUT_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/resources` | [index](endpoints/GET_cluster_ha_resources.md) | +| POST | `/cluster/ha/resources` | [create](endpoints/POST_cluster_ha_resources.md) | +| DELETE | `/cluster/ha/resources/{sid}` | [delete](endpoints/DELETE_cluster_ha_resources_sid.md) | +| GET | `/cluster/ha/resources/{sid}` | [read](endpoints/GET_cluster_ha_resources_sid.md) | +| PUT | `/cluster/ha/resources/{sid}` | [update](endpoints/PUT_cluster_ha_resources_sid.md) | +| POST | `/cluster/ha/resources/{sid}/migrate` | [migrate](endpoints/POST_cluster_ha_resources_sid_migrate.md) | +| POST | `/cluster/ha/resources/{sid}/relocate` | [relocate](endpoints/POST_cluster_ha_resources_sid_relocate.md) | +| GET | `/cluster/ha/rules` | [index](endpoints/GET_cluster_ha_rules.md) | +| POST | `/cluster/ha/rules` | [create_rule](endpoints/POST_cluster_ha_rules.md) | +| DELETE | `/cluster/ha/rules/{rule}` | [delete_rule](endpoints/DELETE_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/rules/{rule}` | [read_rule](endpoints/GET_cluster_ha_rules_rule.md) | +| PUT | `/cluster/ha/rules/{rule}` | [update_rule](endpoints/PUT_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/status` | [index](endpoints/GET_cluster_ha_status.md) | +| POST | `/cluster/ha/status/arm-ha` | [arm-ha](endpoints/POST_cluster_ha_status_arm_ha.md) | +| GET | `/cluster/ha/status/current` | [status](endpoints/GET_cluster_ha_status_current.md) | +| POST | `/cluster/ha/status/disarm-ha` | [disarm-ha](endpoints/POST_cluster_ha_status_disarm_ha.md) | +| GET | `/cluster/ha/status/manager_status` | [manager_status](endpoints/GET_cluster_ha_status_manager_status.md) | +| GET | `/cluster/jobs` | [index](endpoints/GET_cluster_jobs.md) | +| GET | `/cluster/jobs/realm-sync` | [syncjob_index](endpoints/GET_cluster_jobs_realm_sync.md) | +| DELETE | `/cluster/jobs/realm-sync/{id}` | [delete_job](endpoints/DELETE_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/realm-sync/{id}` | [read_job](endpoints/GET_cluster_jobs_realm_sync_id.md) | +| POST | `/cluster/jobs/realm-sync/{id}` | [create_job](endpoints/POST_cluster_jobs_realm_sync_id.md) | +| PUT | `/cluster/jobs/realm-sync/{id}` | [update_job](endpoints/PUT_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/schedule-analyze` | [schedule-analyze](endpoints/GET_cluster_jobs_schedule_analyze.md) | +| GET | `/cluster/log` | [log](endpoints/GET_cluster_log.md) | +| GET | `/cluster/mapping` | [index](endpoints/GET_cluster_mapping.md) | +| GET | `/cluster/mapping/dir` | [index](endpoints/GET_cluster_mapping_dir.md) | +| POST | `/cluster/mapping/dir` | [create](endpoints/POST_cluster_mapping_dir.md) | +| DELETE | `/cluster/mapping/dir/{id}` | [delete](endpoints/DELETE_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/dir/{id}` | [get](endpoints/GET_cluster_mapping_dir_id.md) | +| PUT | `/cluster/mapping/dir/{id}` | [update](endpoints/PUT_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/pci` | [index](endpoints/GET_cluster_mapping_pci.md) | +| POST | `/cluster/mapping/pci` | [create](endpoints/POST_cluster_mapping_pci.md) | +| DELETE | `/cluster/mapping/pci/{id}` | [delete](endpoints/DELETE_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/pci/{id}` | [get](endpoints/GET_cluster_mapping_pci_id.md) | +| PUT | `/cluster/mapping/pci/{id}` | [update](endpoints/PUT_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/usb` | [index](endpoints/GET_cluster_mapping_usb.md) | +| POST | `/cluster/mapping/usb` | [create](endpoints/POST_cluster_mapping_usb.md) | +| DELETE | `/cluster/mapping/usb/{id}` | [delete](endpoints/DELETE_cluster_mapping_usb_id.md) | +| GET | `/cluster/mapping/usb/{id}` | [get](endpoints/GET_cluster_mapping_usb_id.md) | +| PUT | `/cluster/mapping/usb/{id}` | [update](endpoints/PUT_cluster_mapping_usb_id.md) | +| GET | `/cluster/metrics` | [index](endpoints/GET_cluster_metrics.md) | +| GET | `/cluster/metrics/export` | [export](endpoints/GET_cluster_metrics_export.md) | +| GET | `/cluster/metrics/server` | [server_index](endpoints/GET_cluster_metrics_server.md) | +| DELETE | `/cluster/metrics/server/{id}` | [delete](endpoints/DELETE_cluster_metrics_server_id.md) | +| GET | `/cluster/metrics/server/{id}` | [read](endpoints/GET_cluster_metrics_server_id.md) | +| POST | `/cluster/metrics/server/{id}` | [create](endpoints/POST_cluster_metrics_server_id.md) | +| PUT | `/cluster/metrics/server/{id}` | [update](endpoints/PUT_cluster_metrics_server_id.md) | +| GET | `/cluster/nextid` | [nextid](endpoints/GET_cluster_nextid.md) | +| GET | `/cluster/notifications` | [index](endpoints/GET_cluster_notifications.md) | +| GET | `/cluster/notifications/endpoints` | [endpoints_index](endpoints/GET_cluster_notifications_endpoints.md) | +| GET | `/cluster/notifications/endpoints/gotify` | [get_gotify_endpoints](endpoints/GET_cluster_notifications_endpoints_gotify.md) | +| POST | `/cluster/notifications/endpoints/gotify` | [create_gotify_endpoint](endpoints/POST_cluster_notifications_endpoints_gotify.md) | +| DELETE | `/cluster/notifications/endpoints/gotify/{name}` | [delete_gotify_endpoint](endpoints/DELETE_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/gotify/{name}` | [get_gotify_endpoint](endpoints/GET_cluster_notifications_endpoints_gotify_name.md) | +| PUT | `/cluster/notifications/endpoints/gotify/{name}` | [update_gotify_endpoint](endpoints/PUT_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail` | [get_sendmail_endpoints](endpoints/GET_cluster_notifications_endpoints_sendmail.md) | +| POST | `/cluster/notifications/endpoints/sendmail` | [create_sendmail_endpoint](endpoints/POST_cluster_notifications_endpoints_sendmail.md) | +| DELETE | `/cluster/notifications/endpoints/sendmail/{name}` | [delete_sendmail_endpoint](endpoints/DELETE_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail/{name}` | [get_sendmail_endpoint](endpoints/GET_cluster_notifications_endpoints_sendmail_name.md) | +| PUT | `/cluster/notifications/endpoints/sendmail/{name}` | [update_sendmail_endpoint](endpoints/PUT_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/smtp` | [get_smtp_endpoints](endpoints/GET_cluster_notifications_endpoints_smtp.md) | +| POST | `/cluster/notifications/endpoints/smtp` | [create_smtp_endpoint](endpoints/POST_cluster_notifications_endpoints_smtp.md) | +| DELETE | `/cluster/notifications/endpoints/smtp/{name}` | [delete_smtp_endpoint](endpoints/DELETE_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/smtp/{name}` | [get_smtp_endpoint](endpoints/GET_cluster_notifications_endpoints_smtp_name.md) | +| PUT | `/cluster/notifications/endpoints/smtp/{name}` | [update_smtp_endpoint](endpoints/PUT_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/webhook` | [get_webhook_endpoints](endpoints/GET_cluster_notifications_endpoints_webhook.md) | +| POST | `/cluster/notifications/endpoints/webhook` | [create_webhook_endpoint](endpoints/POST_cluster_notifications_endpoints_webhook.md) | +| DELETE | `/cluster/notifications/endpoints/webhook/{name}` | [delete_webhook_endpoint](endpoints/DELETE_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/endpoints/webhook/{name}` | [get_webhook_endpoint](endpoints/GET_cluster_notifications_endpoints_webhook_name.md) | +| PUT | `/cluster/notifications/endpoints/webhook/{name}` | [update_webhook_endpoint](endpoints/PUT_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/matcher-field-values` | [get_matcher_field_values](endpoints/GET_cluster_notifications_matcher_field_values.md) | +| GET | `/cluster/notifications/matcher-fields` | [get_matcher_fields](endpoints/GET_cluster_notifications_matcher_fields.md) | +| GET | `/cluster/notifications/matchers` | [get_matchers](endpoints/GET_cluster_notifications_matchers.md) | +| POST | `/cluster/notifications/matchers` | [create_matcher](endpoints/POST_cluster_notifications_matchers.md) | +| DELETE | `/cluster/notifications/matchers/{name}` | [delete_matcher](endpoints/DELETE_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/matchers/{name}` | [get_matcher](endpoints/GET_cluster_notifications_matchers_name.md) | +| PUT | `/cluster/notifications/matchers/{name}` | [update_matcher](endpoints/PUT_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/targets` | [get_all_targets](endpoints/GET_cluster_notifications_targets.md) | +| POST | `/cluster/notifications/targets/{name}/test` | [test_target](endpoints/POST_cluster_notifications_targets_name_test.md) | +| GET | `/cluster/options` | [get_options](endpoints/GET_cluster_options.md) | +| PUT | `/cluster/options` | [set_options](endpoints/PUT_cluster_options.md) | +| GET | `/cluster/qemu` | [index](endpoints/GET_cluster_qemu.md) | +| GET | `/cluster/qemu/cpu-flags` | [index](endpoints/GET_cluster_qemu_cpu_flags.md) | +| GET | `/cluster/qemu/custom-cpu-models` | [config](endpoints/GET_cluster_qemu_custom_cpu_models.md) | +| POST | `/cluster/qemu/custom-cpu-models` | [create](endpoints/POST_cluster_qemu_custom_cpu_models.md) | +| DELETE | `/cluster/qemu/custom-cpu-models/{cputype}` | [delete](endpoints/DELETE_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/qemu/custom-cpu-models/{cputype}` | [info](endpoints/GET_cluster_qemu_custom_cpu_models_cputype.md) | +| PUT | `/cluster/qemu/custom-cpu-models/{cputype}` | [update](endpoints/PUT_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/replication` | [index](endpoints/GET_cluster_replication.md) | +| POST | `/cluster/replication` | [create](endpoints/POST_cluster_replication.md) | +| DELETE | `/cluster/replication/{id}` | [delete](endpoints/DELETE_cluster_replication_id.md) | +| GET | `/cluster/replication/{id}` | [read](endpoints/GET_cluster_replication_id.md) | +| PUT | `/cluster/replication/{id}` | [update](endpoints/PUT_cluster_replication_id.md) | +| GET | `/cluster/resources` | [resources](endpoints/GET_cluster_resources.md) | +| GET | `/cluster/sdn` | [index](endpoints/GET_cluster_sdn.md) | +| PUT | `/cluster/sdn` | [reload](endpoints/PUT_cluster_sdn.md) | +| GET | `/cluster/sdn/controllers` | [index](endpoints/GET_cluster_sdn_controllers.md) | +| POST | `/cluster/sdn/controllers` | [create](endpoints/POST_cluster_sdn_controllers.md) | +| DELETE | `/cluster/sdn/controllers/{controller}` | [delete](endpoints/DELETE_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/controllers/{controller}` | [read](endpoints/GET_cluster_sdn_controllers_controller.md) | +| PUT | `/cluster/sdn/controllers/{controller}` | [update](endpoints/PUT_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/dns` | [index](endpoints/GET_cluster_sdn_dns.md) | +| POST | `/cluster/sdn/dns` | [create](endpoints/POST_cluster_sdn_dns.md) | +| DELETE | `/cluster/sdn/dns/{dns}` | [delete](endpoints/DELETE_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dns/{dns}` | [read](endpoints/GET_cluster_sdn_dns_dns.md) | +| PUT | `/cluster/sdn/dns/{dns}` | [update](endpoints/PUT_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dry-run` | [dry-run](endpoints/GET_cluster_sdn_dry_run.md) | +| GET | `/cluster/sdn/fabrics` | [index](endpoints/GET_cluster_sdn_fabrics.md) | +| GET | `/cluster/sdn/fabrics/all` | [list_all](endpoints/GET_cluster_sdn_fabrics_all.md) | +| GET | `/cluster/sdn/fabrics/fabric` | [index](endpoints/GET_cluster_sdn_fabrics_fabric.md) | +| POST | `/cluster/sdn/fabrics/fabric` | [add_fabric](endpoints/POST_cluster_sdn_fabrics_fabric.md) | +| DELETE | `/cluster/sdn/fabrics/fabric/{id}` | [delete_fabric](endpoints/DELETE_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/fabric/{id}` | [get_fabric](endpoints/GET_cluster_sdn_fabrics_fabric_id.md) | +| PUT | `/cluster/sdn/fabrics/fabric/{id}` | [update_fabric](endpoints/PUT_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/node` | [list_nodes](endpoints/GET_cluster_sdn_fabrics_node.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}` | [list_nodes_fabric](endpoints/GET_cluster_sdn_fabrics_node_fabric_id.md) | +| POST | `/cluster/sdn/fabrics/node/{fabric_id}` | [add_node](endpoints/POST_cluster_sdn_fabrics_node_fabric_id.md) | +| DELETE | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [delete_node](endpoints/DELETE_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [get_node](endpoints/GET_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| PUT | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [update_node](endpoints/PUT_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/ipams` | [index](endpoints/GET_cluster_sdn_ipams.md) | +| POST | `/cluster/sdn/ipams` | [create](endpoints/POST_cluster_sdn_ipams.md) | +| DELETE | `/cluster/sdn/ipams/{ipam}` | [delete](endpoints/DELETE_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}` | [read](endpoints/GET_cluster_sdn_ipams_ipam.md) | +| PUT | `/cluster/sdn/ipams/{ipam}` | [update](endpoints/PUT_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}/status` | [ipamindex](endpoints/GET_cluster_sdn_ipams_ipam_status.md) | +| DELETE | `/cluster/sdn/lock` | [release_lock](endpoints/DELETE_cluster_sdn_lock.md) | +| POST | `/cluster/sdn/lock` | [lock](endpoints/POST_cluster_sdn_lock.md) | +| GET | `/cluster/sdn/prefix-lists` | [list_prefix_lists](endpoints/GET_cluster_sdn_prefix_lists.md) | +| POST | `/cluster/sdn/prefix-lists` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}` | [delete_prefix_list](endpoints/DELETE_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}` | [get_prefix_list](endpoints/GET_cluster_sdn_prefix_lists_id.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}` | [update_prefix_list](endpoints/PUT_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries` | [get_prefix_list_entries](endpoints/GET_cluster_sdn_prefix_lists_id_entries.md) | +| POST | `/cluster/sdn/prefix-lists/{id}/entries` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists_id_entries.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [delete_prefix_list_entry](endpoints/DELETE_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [get_prefix_list_entry](endpoints/GET_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [update_prefix_list_entry](endpoints/PUT_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| POST | `/cluster/sdn/rollback` | [rollback](endpoints/POST_cluster_sdn_rollback.md) | +| GET | `/cluster/sdn/route-maps` | [list_route_maps](endpoints/GET_cluster_sdn_route_maps.md) | +| GET | `/cluster/sdn/route-maps/entries` | [list_route_map_entries](endpoints/GET_cluster_sdn_route_maps_entries.md) | +| POST | `/cluster/sdn/route-maps/entries` | [create_route_map_entry](endpoints/POST_cluster_sdn_route_maps_entries.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}` | [list_route_map_entries_for_route_map](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id.md) | +| DELETE | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [delete_route_map_entry](endpoints/DELETE_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [get_route_map_entry](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| PUT | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [update_route_map_entry](endpoints/PUT_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/vnets` | [index](endpoints/GET_cluster_sdn_vnets.md) | +| POST | `/cluster/sdn/vnets` | [create](endpoints/POST_cluster_sdn_vnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall` | [index](endpoints/GET_cluster_sdn_vnets_vnet_firewall.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/options` | [get_options](endpoints/GET_cluster_sdn_vnets_vnet_firewall_options.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/options` | [set_options](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_options.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [get_rules](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules.md) | +| POST | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [create_rule](endpoints/POST_cluster_sdn_vnets_vnet_firewall_rules.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/ips` | [ipdelete](endpoints/DELETE_cluster_sdn_vnets_vnet_ips.md) | +| POST | `/cluster/sdn/vnets/{vnet}/ips` | [ipcreate](endpoints/POST_cluster_sdn_vnets_vnet_ips.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/ips` | [ipupdate](endpoints/PUT_cluster_sdn_vnets_vnet_ips.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets` | [index](endpoints/GET_cluster_sdn_vnets_vnet_subnets.md) | +| POST | `/cluster/sdn/vnets/{vnet}/subnets` | [create](endpoints/POST_cluster_sdn_vnets_vnet_subnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/zones` | [index](endpoints/GET_cluster_sdn_zones.md) | +| POST | `/cluster/sdn/zones` | [create](endpoints/POST_cluster_sdn_zones.md) | +| DELETE | `/cluster/sdn/zones/{zone}` | [delete](endpoints/DELETE_cluster_sdn_zones_zone.md) | +| GET | `/cluster/sdn/zones/{zone}` | [read](endpoints/GET_cluster_sdn_zones_zone.md) | +| PUT | `/cluster/sdn/zones/{zone}` | [update](endpoints/PUT_cluster_sdn_zones_zone.md) | +| GET | `/cluster/status` | [get_status](endpoints/GET_cluster_status.md) | +| GET | `/cluster/tasks` | [tasks](endpoints/GET_cluster_tasks.md) | +| GET | `/nodes` | [index](endpoints/GET_nodes.md) | +| GET | `/nodes/{node}` | [index](endpoints/GET_nodes_node.md) | +| GET | `/nodes/{node}/aplinfo` | [aplinfo](endpoints/GET_nodes_node_aplinfo.md) | +| POST | `/nodes/{node}/aplinfo` | [apl_download](endpoints/POST_nodes_node_aplinfo.md) | +| GET | `/nodes/{node}/apt` | [index](endpoints/GET_nodes_node_apt.md) | +| GET | `/nodes/{node}/apt/changelog` | [changelog](endpoints/GET_nodes_node_apt_changelog.md) | +| GET | `/nodes/{node}/apt/repositories` | [repositories](endpoints/GET_nodes_node_apt_repositories.md) | +| POST | `/nodes/{node}/apt/repositories` | [change_repository](endpoints/POST_nodes_node_apt_repositories.md) | +| PUT | `/nodes/{node}/apt/repositories` | [add_repository](endpoints/PUT_nodes_node_apt_repositories.md) | +| GET | `/nodes/{node}/apt/update` | [list_updates](endpoints/GET_nodes_node_apt_update.md) | +| POST | `/nodes/{node}/apt/update` | [update_database](endpoints/POST_nodes_node_apt_update.md) | +| GET | `/nodes/{node}/apt/versions` | [versions](endpoints/GET_nodes_node_apt_versions.md) | +| GET | `/nodes/{node}/capabilities` | [index](endpoints/GET_nodes_node_capabilities.md) | +| GET | `/nodes/{node}/capabilities/qemu` | [qemu_caps_index](endpoints/GET_nodes_node_capabilities_qemu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu-flags` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu_flags.md) | +| GET | `/nodes/{node}/capabilities/qemu/machines` | [types](endpoints/GET_nodes_node_capabilities_qemu_machines.md) | +| GET | `/nodes/{node}/capabilities/qemu/migration` | [capabilities](endpoints/GET_nodes_node_capabilities_qemu_migration.md) | +| GET | `/nodes/{node}/ceph` | [index](endpoints/GET_nodes_node_ceph.md) | +| GET | `/nodes/{node}/ceph/cfg` | [index](endpoints/GET_nodes_node_ceph_cfg.md) | +| GET | `/nodes/{node}/ceph/cfg/db` | [db](endpoints/GET_nodes_node_ceph_cfg_db.md) | +| GET | `/nodes/{node}/ceph/cfg/raw` | [raw](endpoints/GET_nodes_node_ceph_cfg_raw.md) | +| GET | `/nodes/{node}/ceph/cfg/value` | [value](endpoints/GET_nodes_node_ceph_cfg_value.md) | +| GET | `/nodes/{node}/ceph/cmd-safety` | [cmd_safety](endpoints/GET_nodes_node_ceph_cmd_safety.md) | +| GET | `/nodes/{node}/ceph/crush` | [crush](endpoints/GET_nodes_node_ceph_crush.md) | +| GET | `/nodes/{node}/ceph/fs` | [index](endpoints/GET_nodes_node_ceph_fs.md) | +| DELETE | `/nodes/{node}/ceph/fs/{name}` | [destroyfs](endpoints/DELETE_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/fs/{name}` | [createfs](endpoints/POST_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/init` | [init](endpoints/POST_nodes_node_ceph_init.md) | +| GET | `/nodes/{node}/ceph/log` | [log](endpoints/GET_nodes_node_ceph_log.md) | +| GET | `/nodes/{node}/ceph/mds` | [index](endpoints/GET_nodes_node_ceph_mds.md) | +| DELETE | `/nodes/{node}/ceph/mds/{name}` | [destroymds](endpoints/DELETE_nodes_node_ceph_mds_name.md) | +| POST | `/nodes/{node}/ceph/mds/{name}` | [createmds](endpoints/POST_nodes_node_ceph_mds_name.md) | +| GET | `/nodes/{node}/ceph/mgr` | [index](endpoints/GET_nodes_node_ceph_mgr.md) | +| DELETE | `/nodes/{node}/ceph/mgr/{id}` | [destroymgr](endpoints/DELETE_nodes_node_ceph_mgr_id.md) | +| POST | `/nodes/{node}/ceph/mgr/{id}` | [createmgr](endpoints/POST_nodes_node_ceph_mgr_id.md) | +| GET | `/nodes/{node}/ceph/mon` | [listmon](endpoints/GET_nodes_node_ceph_mon.md) | +| DELETE | `/nodes/{node}/ceph/mon/{monid}` | [destroymon](endpoints/DELETE_nodes_node_ceph_mon_monid.md) | +| POST | `/nodes/{node}/ceph/mon/{monid}` | [createmon](endpoints/POST_nodes_node_ceph_mon_monid.md) | +| GET | `/nodes/{node}/ceph/osd` | [index](endpoints/GET_nodes_node_ceph_osd.md) | +| POST | `/nodes/{node}/ceph/osd` | [createosd](endpoints/POST_nodes_node_ceph_osd.md) | +| DELETE | `/nodes/{node}/ceph/osd/{osdid}` | [destroyosd](endpoints/DELETE_nodes_node_ceph_osd_osdid.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}` | [osdindex](endpoints/GET_nodes_node_ceph_osd_osdid.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/in` | [in](endpoints/POST_nodes_node_ceph_osd_osdid_in.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/lv-info` | [osdvolume](endpoints/GET_nodes_node_ceph_osd_osdid_lv_info.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/metadata` | [osddetails](endpoints/GET_nodes_node_ceph_osd_osdid_metadata.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/out` | [out](endpoints/POST_nodes_node_ceph_osd_osdid_out.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/scrub` | [scrub](endpoints/POST_nodes_node_ceph_osd_osdid_scrub.md) | +| GET | `/nodes/{node}/ceph/pool` | [lspools](endpoints/GET_nodes_node_ceph_pool.md) | +| POST | `/nodes/{node}/ceph/pool` | [createpool](endpoints/POST_nodes_node_ceph_pool.md) | +| DELETE | `/nodes/{node}/ceph/pool/{name}` | [destroypool](endpoints/DELETE_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}` | [poolindex](endpoints/GET_nodes_node_ceph_pool_name.md) | +| PUT | `/nodes/{node}/ceph/pool/{name}` | [setpool](endpoints/PUT_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}/status` | [getpool](endpoints/GET_nodes_node_ceph_pool_name_status.md) | +| POST | `/nodes/{node}/ceph/restart` | [restart](endpoints/POST_nodes_node_ceph_restart.md) | +| GET | `/nodes/{node}/ceph/rules` | [rules](endpoints/GET_nodes_node_ceph_rules.md) | +| POST | `/nodes/{node}/ceph/start` | [start](endpoints/POST_nodes_node_ceph_start.md) | +| GET | `/nodes/{node}/ceph/status` | [status](endpoints/GET_nodes_node_ceph_status.md) | +| POST | `/nodes/{node}/ceph/stop` | [stop](endpoints/POST_nodes_node_ceph_stop.md) | +| GET | `/nodes/{node}/certificates` | [index](endpoints/GET_nodes_node_certificates.md) | +| GET | `/nodes/{node}/certificates/acme` | [index](endpoints/GET_nodes_node_certificates_acme.md) | +| DELETE | `/nodes/{node}/certificates/acme/certificate` | [revoke_certificate](endpoints/DELETE_nodes_node_certificates_acme_certificate.md) | +| POST | `/nodes/{node}/certificates/acme/certificate` | [new_certificate](endpoints/POST_nodes_node_certificates_acme_certificate.md) | +| PUT | `/nodes/{node}/certificates/acme/certificate` | [renew_certificate](endpoints/PUT_nodes_node_certificates_acme_certificate.md) | +| DELETE | `/nodes/{node}/certificates/custom` | [remove_custom_cert](endpoints/DELETE_nodes_node_certificates_custom.md) | +| POST | `/nodes/{node}/certificates/custom` | [upload_custom_cert](endpoints/POST_nodes_node_certificates_custom.md) | +| GET | `/nodes/{node}/certificates/info` | [info](endpoints/GET_nodes_node_certificates_info.md) | +| GET | `/nodes/{node}/config` | [get_config](endpoints/GET_nodes_node_config.md) | +| PUT | `/nodes/{node}/config` | [set_options](endpoints/PUT_nodes_node_config.md) | +| GET | `/nodes/{node}/disks` | [index](endpoints/GET_nodes_node_disks.md) | +| GET | `/nodes/{node}/disks/directory` | [index](endpoints/GET_nodes_node_disks_directory.md) | +| POST | `/nodes/{node}/disks/directory` | [create](endpoints/POST_nodes_node_disks_directory.md) | +| DELETE | `/nodes/{node}/disks/directory/{name}` | [delete](endpoints/DELETE_nodes_node_disks_directory_name.md) | +| POST | `/nodes/{node}/disks/initgpt` | [initgpt](endpoints/POST_nodes_node_disks_initgpt.md) | +| GET | `/nodes/{node}/disks/list` | [list](endpoints/GET_nodes_node_disks_list.md) | +| GET | `/nodes/{node}/disks/lvm` | [index](endpoints/GET_nodes_node_disks_lvm.md) | +| POST | `/nodes/{node}/disks/lvm` | [create](endpoints/POST_nodes_node_disks_lvm.md) | +| DELETE | `/nodes/{node}/disks/lvm/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvm_name.md) | +| GET | `/nodes/{node}/disks/lvmthin` | [index](endpoints/GET_nodes_node_disks_lvmthin.md) | +| POST | `/nodes/{node}/disks/lvmthin` | [create](endpoints/POST_nodes_node_disks_lvmthin.md) | +| DELETE | `/nodes/{node}/disks/lvmthin/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvmthin_name.md) | +| GET | `/nodes/{node}/disks/smart` | [smart](endpoints/GET_nodes_node_disks_smart.md) | +| PUT | `/nodes/{node}/disks/wipedisk` | [wipe_disk](endpoints/PUT_nodes_node_disks_wipedisk.md) | +| GET | `/nodes/{node}/disks/zfs` | [index](endpoints/GET_nodes_node_disks_zfs.md) | +| POST | `/nodes/{node}/disks/zfs` | [create](endpoints/POST_nodes_node_disks_zfs.md) | +| DELETE | `/nodes/{node}/disks/zfs/{name}` | [delete](endpoints/DELETE_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/disks/zfs/{name}` | [detail](endpoints/GET_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/dns` | [dns](endpoints/GET_nodes_node_dns.md) | +| PUT | `/nodes/{node}/dns` | [update_dns](endpoints/PUT_nodes_node_dns.md) | +| POST | `/nodes/{node}/execute` | [execute](endpoints/POST_nodes_node_execute.md) | +| GET | `/nodes/{node}/firewall` | [index](endpoints/GET_nodes_node_firewall.md) | +| GET | `/nodes/{node}/firewall/log` | [log](endpoints/GET_nodes_node_firewall_log.md) | +| GET | `/nodes/{node}/firewall/options` | [get_options](endpoints/GET_nodes_node_firewall_options.md) | +| PUT | `/nodes/{node}/firewall/options` | [set_options](endpoints/PUT_nodes_node_firewall_options.md) | +| GET | `/nodes/{node}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_firewall_rules.md) | +| POST | `/nodes/{node}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_firewall_rules.md) | +| DELETE | `/nodes/{node}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/hardware` | [index](endpoints/GET_nodes_node_hardware.md) | +| GET | `/nodes/{node}/hardware/pci` | [pci_scan](endpoints/GET_nodes_node_hardware_pci.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}` | [pci_index](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev` | [mdevscan](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping_mdev.md) | +| GET | `/nodes/{node}/hardware/usb` | [usbscan](endpoints/GET_nodes_node_hardware_usb.md) | +| GET | `/nodes/{node}/hosts` | [get_etc_hosts](endpoints/GET_nodes_node_hosts.md) | +| POST | `/nodes/{node}/hosts` | [write_etc_hosts](endpoints/POST_nodes_node_hosts.md) | +| GET | `/nodes/{node}/journal` | [journal](endpoints/GET_nodes_node_journal.md) | +| GET | `/nodes/{node}/lxc` | [vmlist](endpoints/GET_nodes_node_lxc.md) | +| POST | `/nodes/{node}/lxc` | [create_vm](endpoints/POST_nodes_node_lxc.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_lxc_vmid.md) | +| GET | `/nodes/{node}/lxc/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_lxc_vmid.md) | +| POST | `/nodes/{node}/lxc/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_lxc_vmid_clone.md) | +| GET | `/nodes/{node}/lxc/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_lxc_vmid_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_lxc_vmid_config.md) | +| GET | `/nodes/{node}/lxc/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_lxc_vmid_feature.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall` | [index](endpoints/GET_nodes_node_lxc_vmid_firewall.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_lxc_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_lxc_vmid_firewall_log.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_lxc_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_lxc_vmid_firewall_options.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_lxc_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_lxc_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_lxc_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/interfaces` | [ip](endpoints/GET_nodes_node_lxc_vmid_interfaces.md) | +| GET | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/move_volume` | [move_volume](endpoints/POST_nodes_node_lxc_vmid_move_volume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_lxc_vmid_mtunnel.md) | +| GET | `/nodes/{node}/lxc/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_lxc_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/lxc/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_lxc_vmid_pending.md) | +| POST | `/nodes/{node}/lxc/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_lxc_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_lxc_vmid_resize.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_lxc_vmid_rrd.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_lxc_vmid_rrddata.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot` | [list](endpoints/GET_nodes_node_lxc_vmid_snapshot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_lxc_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_lxc_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/lxc/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_lxc_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_lxc_vmid_status.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_lxc_vmid_status_current.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_lxc_vmid_status_reboot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_lxc_vmid_status_resume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_lxc_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_lxc_vmid_status_start.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_lxc_vmid_status_stop.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_lxc_vmid_status_suspend.md) | +| POST | `/nodes/{node}/lxc/{vmid}/template` | [template](endpoints/POST_nodes_node_lxc_vmid_template.md) | +| POST | `/nodes/{node}/lxc/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_lxc_vmid_termproxy.md) | +| POST | `/nodes/{node}/lxc/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_lxc_vmid_vncproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_lxc_vmid_vncwebsocket.md) | +| POST | `/nodes/{node}/migrateall` | [migrateall](endpoints/POST_nodes_node_migrateall.md) | +| GET | `/nodes/{node}/netstat` | [netstat](endpoints/GET_nodes_node_netstat.md) | +| DELETE | `/nodes/{node}/network` | [revert_network_changes](endpoints/DELETE_nodes_node_network.md) | +| GET | `/nodes/{node}/network` | [index](endpoints/GET_nodes_node_network.md) | +| POST | `/nodes/{node}/network` | [create_network](endpoints/POST_nodes_node_network.md) | +| PUT | `/nodes/{node}/network` | [reload_network_config](endpoints/PUT_nodes_node_network.md) | +| DELETE | `/nodes/{node}/network/{iface}` | [delete_network](endpoints/DELETE_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/network/{iface}` | [network_config](endpoints/GET_nodes_node_network_iface.md) | +| PUT | `/nodes/{node}/network/{iface}` | [update_network](endpoints/PUT_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/qemu` | [vmlist](endpoints/GET_nodes_node_qemu.md) | +| POST | `/nodes/{node}/qemu` | [create_vm](endpoints/POST_nodes_node_qemu.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent` | [index](endpoints/GET_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent` | [agent](endpoints/POST_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/exec` | [exec](endpoints/POST_nodes_node_qemu_vmid_agent_exec.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/exec-status` | [exec-status](endpoints/GET_nodes_node_qemu_vmid_agent_exec_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/file-read` | [file-read](endpoints/GET_nodes_node_qemu_vmid_agent_file_read.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/file-write` | [file-write](endpoints/POST_nodes_node_qemu_vmid_agent_file_write.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze` | [fsfreeze-freeze](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_freeze.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status` | [fsfreeze-status](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_status.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw` | [fsfreeze-thaw](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_thaw.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fstrim` | [fstrim](endpoints/POST_nodes_node_qemu_vmid_agent_fstrim.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-fsinfo` | [get-fsinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_fsinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-host-name` | [get-host-name](endpoints/GET_nodes_node_qemu_vmid_agent_get_host_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info` | [get-memory-block-info](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_block_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks` | [get-memory-blocks](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_blocks.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-osinfo` | [get-osinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_osinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-time` | [get-time](endpoints/GET_nodes_node_qemu_vmid_agent_get_time.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-timezone` | [get-timezone](endpoints/GET_nodes_node_qemu_vmid_agent_get_timezone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-users` | [get-users](endpoints/GET_nodes_node_qemu_vmid_agent_get_users.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-vcpus` | [get-vcpus](endpoints/GET_nodes_node_qemu_vmid_agent_get_vcpus.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/info` | [info](endpoints/GET_nodes_node_qemu_vmid_agent_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces` | [network-get-interfaces](endpoints/GET_nodes_node_qemu_vmid_agent_network_get_interfaces.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/ping` | [ping](endpoints/POST_nodes_node_qemu_vmid_agent_ping.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/set-user-password` | [set-user-password](endpoints/POST_nodes_node_qemu_vmid_agent_set_user_password.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/shutdown` | [shutdown](endpoints/POST_nodes_node_qemu_vmid_agent_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-disk` | [suspend-disk](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid` | [suspend-hybrid](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_hybrid.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-ram` | [suspend-ram](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_ram.md) | +| POST | `/nodes/{node}/qemu/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_qemu_vmid_clone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_pending](endpoints/GET_nodes_node_qemu_vmid_cloudinit.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_update](endpoints/PUT_nodes_node_qemu_vmid_cloudinit.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit/dump` | [cloudinit_generated_config_dump](endpoints/GET_nodes_node_qemu_vmid_cloudinit_dump.md) | +| GET | `/nodes/{node}/qemu/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/config` | [update_vm_async](endpoints/POST_nodes_node_qemu_vmid_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/dbus-vmstate` | [dbus_vmstate](endpoints/POST_nodes_node_qemu_vmid_dbus_vmstate.md) | +| GET | `/nodes/{node}/qemu/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_qemu_vmid_feature.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall` | [index](endpoints/GET_nodes_node_qemu_vmid_firewall.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_qemu_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_qemu_vmid_firewall_log.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_qemu_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_qemu_vmid_firewall_options.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_qemu_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_qemu_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_qemu_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/monitor` | [monitor](endpoints/POST_nodes_node_qemu_vmid_monitor.md) | +| POST | `/nodes/{node}/qemu/{vmid}/move_disk` | [move_vm_disk](endpoints/POST_nodes_node_qemu_vmid_move_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_qemu_vmid_mtunnel.md) | +| GET | `/nodes/{node}/qemu/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_qemu_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/qemu/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_qemu_vmid_pending.md) | +| POST | `/nodes/{node}/qemu/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_qemu_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_qemu_vmid_resize.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_qemu_vmid_rrd.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_qemu_vmid_rrddata.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/sendkey` | [vm_sendkey](endpoints/PUT_nodes_node_qemu_vmid_sendkey.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot_list](endpoints/GET_nodes_node_qemu_vmid_snapshot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_qemu_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_qemu_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/qemu/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_qemu_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_qemu_vmid_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_qemu_vmid_status_current.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_qemu_vmid_status_reboot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reset` | [vm_reset](endpoints/POST_nodes_node_qemu_vmid_status_reset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_qemu_vmid_status_resume.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_qemu_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_qemu_vmid_status_start.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_qemu_vmid_status_stop.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_qemu_vmid_status_suspend.md) | +| POST | `/nodes/{node}/qemu/{vmid}/template` | [template](endpoints/POST_nodes_node_qemu_vmid_template.md) | +| POST | `/nodes/{node}/qemu/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_qemu_vmid_termproxy.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/unlink` | [unlink](endpoints/PUT_nodes_node_qemu_vmid_unlink.md) | +| POST | `/nodes/{node}/qemu/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_qemu_vmid_vncproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_qemu_vmid_vncwebsocket.md) | +| GET | `/nodes/{node}/query-oci-repo-tags` | [query_oci_repo_tags](endpoints/GET_nodes_node_query_oci_repo_tags.md) | +| GET | `/nodes/{node}/query-url-metadata` | [query_url_metadata](endpoints/GET_nodes_node_query_url_metadata.md) | +| GET | `/nodes/{node}/replication` | [status](endpoints/GET_nodes_node_replication.md) | +| GET | `/nodes/{node}/replication/{id}` | [index](endpoints/GET_nodes_node_replication_id.md) | +| GET | `/nodes/{node}/replication/{id}/log` | [read_job_log](endpoints/GET_nodes_node_replication_id_log.md) | +| POST | `/nodes/{node}/replication/{id}/schedule_now` | [schedule_now](endpoints/POST_nodes_node_replication_id_schedule_now.md) | +| GET | `/nodes/{node}/replication/{id}/status` | [job_status](endpoints/GET_nodes_node_replication_id_status.md) | +| GET | `/nodes/{node}/report` | [report](endpoints/GET_nodes_node_report.md) | +| GET | `/nodes/{node}/rrd` | [rrd](endpoints/GET_nodes_node_rrd.md) | +| GET | `/nodes/{node}/rrddata` | [rrddata](endpoints/GET_nodes_node_rrddata.md) | +| GET | `/nodes/{node}/scan` | [index](endpoints/GET_nodes_node_scan.md) | +| GET | `/nodes/{node}/scan/cifs` | [cifsscan](endpoints/GET_nodes_node_scan_cifs.md) | +| GET | `/nodes/{node}/scan/iscsi` | [iscsiscan](endpoints/GET_nodes_node_scan_iscsi.md) | +| GET | `/nodes/{node}/scan/lvm` | [lvmscan](endpoints/GET_nodes_node_scan_lvm.md) | +| GET | `/nodes/{node}/scan/lvmthin` | [lvmthinscan](endpoints/GET_nodes_node_scan_lvmthin.md) | +| GET | `/nodes/{node}/scan/nfs` | [nfsscan](endpoints/GET_nodes_node_scan_nfs.md) | +| GET | `/nodes/{node}/scan/pbs` | [pbsscan](endpoints/GET_nodes_node_scan_pbs.md) | +| GET | `/nodes/{node}/scan/zfs` | [zfsscan](endpoints/GET_nodes_node_scan_zfs.md) | +| GET | `/nodes/{node}/sdn` | [sdnindex](endpoints/GET_nodes_node_sdn.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}` | [diridx](endpoints/GET_nodes_node_sdn_fabrics_fabric.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/interfaces` | [interfaces](endpoints/GET_nodes_node_sdn_fabrics_fabric_interfaces.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/neighbors` | [neighbors](endpoints/GET_nodes_node_sdn_fabrics_fabric_neighbors.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/routes` | [routes](endpoints/GET_nodes_node_sdn_fabrics_fabric_routes.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}` | [diridx](endpoints/GET_nodes_node_sdn_vnets_vnet.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}/mac-vrf` | [mac-vrf](endpoints/GET_nodes_node_sdn_vnets_vnet_mac_vrf.md) | +| GET | `/nodes/{node}/sdn/zones` | [index](endpoints/GET_nodes_node_sdn_zones.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}` | [diridx](endpoints/GET_nodes_node_sdn_zones_zone.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/bridges` | [bridges](endpoints/GET_nodes_node_sdn_zones_zone_bridges.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/content` | [index](endpoints/GET_nodes_node_sdn_zones_zone_content.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/ip-vrf` | [ip-vrf](endpoints/GET_nodes_node_sdn_zones_zone_ip_vrf.md) | +| GET | `/nodes/{node}/services` | [index](endpoints/GET_nodes_node_services.md) | +| GET | `/nodes/{node}/services/{service}` | [srvcmdidx](endpoints/GET_nodes_node_services_service.md) | +| POST | `/nodes/{node}/services/{service}/reload` | [service_reload](endpoints/POST_nodes_node_services_service_reload.md) | +| POST | `/nodes/{node}/services/{service}/restart` | [service_restart](endpoints/POST_nodes_node_services_service_restart.md) | +| POST | `/nodes/{node}/services/{service}/start` | [service_start](endpoints/POST_nodes_node_services_service_start.md) | +| GET | `/nodes/{node}/services/{service}/state` | [service_state](endpoints/GET_nodes_node_services_service_state.md) | +| POST | `/nodes/{node}/services/{service}/stop` | [service_stop](endpoints/POST_nodes_node_services_service_stop.md) | +| POST | `/nodes/{node}/spiceshell` | [spiceshell](endpoints/POST_nodes_node_spiceshell.md) | +| POST | `/nodes/{node}/startall` | [startall](endpoints/POST_nodes_node_startall.md) | +| GET | `/nodes/{node}/status` | [status](endpoints/GET_nodes_node_status.md) | +| POST | `/nodes/{node}/status` | [node_cmd](endpoints/POST_nodes_node_status.md) | +| POST | `/nodes/{node}/stopall` | [stopall](endpoints/POST_nodes_node_stopall.md) | +| GET | `/nodes/{node}/storage` | [index](endpoints/GET_nodes_node_storage.md) | +| GET | `/nodes/{node}/storage/{storage}` | [diridx](endpoints/GET_nodes_node_storage_storage.md) | +| GET | `/nodes/{node}/storage/{storage}/content` | [index](endpoints/GET_nodes_node_storage_storage_content.md) | +| POST | `/nodes/{node}/storage/{storage}/content` | [create](endpoints/POST_nodes_node_storage_storage_content.md) | +| DELETE | `/nodes/{node}/storage/{storage}/content/{volume}` | [delete](endpoints/DELETE_nodes_node_storage_storage_content_volume.md) | +| GET | `/nodes/{node}/storage/{storage}/content/{volume}` | [info](endpoints/GET_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/content/{volume}` | [copy](endpoints/POST_nodes_node_storage_storage_content_volume.md) | +| PUT | `/nodes/{node}/storage/{storage}/content/{volume}` | [updateattributes](endpoints/PUT_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/download-url` | [download_url](endpoints/POST_nodes_node_storage_storage_download_url.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/download` | [download](endpoints/GET_nodes_node_storage_storage_file_restore_download.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/list` | [list](endpoints/GET_nodes_node_storage_storage_file_restore_list.md) | +| GET | `/nodes/{node}/storage/{storage}/identity` | [identity](endpoints/GET_nodes_node_storage_storage_identity.md) | +| GET | `/nodes/{node}/storage/{storage}/import-metadata` | [get_import_metadata](endpoints/GET_nodes_node_storage_storage_import_metadata.md) | +| POST | `/nodes/{node}/storage/{storage}/oci-registry-pull` | [oci_registry_pull](endpoints/POST_nodes_node_storage_storage_oci_registry_pull.md) | +| DELETE | `/nodes/{node}/storage/{storage}/prunebackups` | [delete](endpoints/DELETE_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/prunebackups` | [dryrun](endpoints/GET_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/rrd` | [rrd](endpoints/GET_nodes_node_storage_storage_rrd.md) | +| GET | `/nodes/{node}/storage/{storage}/rrddata` | [rrddata](endpoints/GET_nodes_node_storage_storage_rrddata.md) | +| GET | `/nodes/{node}/storage/{storage}/status` | [read_status](endpoints/GET_nodes_node_storage_storage_status.md) | +| POST | `/nodes/{node}/storage/{storage}/upload` | [upload](endpoints/POST_nodes_node_storage_storage_upload.md) | +| DELETE | `/nodes/{node}/subscription` | [delete](endpoints/DELETE_nodes_node_subscription.md) | +| GET | `/nodes/{node}/subscription` | [get](endpoints/GET_nodes_node_subscription.md) | +| POST | `/nodes/{node}/subscription` | [update](endpoints/POST_nodes_node_subscription.md) | +| PUT | `/nodes/{node}/subscription` | [set](endpoints/PUT_nodes_node_subscription.md) | +| POST | `/nodes/{node}/suspendall` | [suspendall](endpoints/POST_nodes_node_suspendall.md) | +| GET | `/nodes/{node}/syslog` | [syslog](endpoints/GET_nodes_node_syslog.md) | +| GET | `/nodes/{node}/tasks` | [node_tasks](endpoints/GET_nodes_node_tasks.md) | +| DELETE | `/nodes/{node}/tasks/{upid}` | [stop_task](endpoints/DELETE_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}` | [upid_index](endpoints/GET_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}/log` | [read_task_log](endpoints/GET_nodes_node_tasks_upid_log.md) | +| GET | `/nodes/{node}/tasks/{upid}/status` | [read_task_status](endpoints/GET_nodes_node_tasks_upid_status.md) | +| POST | `/nodes/{node}/termproxy` | [termproxy](endpoints/POST_nodes_node_termproxy.md) | +| GET | `/nodes/{node}/time` | [time](endpoints/GET_nodes_node_time.md) | +| PUT | `/nodes/{node}/time` | [set_timezone](endpoints/PUT_nodes_node_time.md) | +| GET | `/nodes/{node}/version` | [version](endpoints/GET_nodes_node_version.md) | +| POST | `/nodes/{node}/vncshell` | [vncshell](endpoints/POST_nodes_node_vncshell.md) | +| GET | `/nodes/{node}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_vncwebsocket.md) | +| POST | `/nodes/{node}/vzdump` | [vzdump](endpoints/POST_nodes_node_vzdump.md) | +| GET | `/nodes/{node}/vzdump/defaults` | [defaults](endpoints/GET_nodes_node_vzdump_defaults.md) | +| GET | `/nodes/{node}/vzdump/extractconfig` | [extractconfig](endpoints/GET_nodes_node_vzdump_extractconfig.md) | +| POST | `/nodes/{node}/wakeonlan` | [wakeonlan](endpoints/POST_nodes_node_wakeonlan.md) | +| DELETE | `/pools` | [delete_pool](endpoints/DELETE_pools.md) | +| GET | `/pools` | [index](endpoints/GET_pools.md) | +| POST | `/pools` | [create_pool](endpoints/POST_pools.md) | +| PUT | `/pools` | [update_pool](endpoints/PUT_pools.md) | +| DELETE | `/pools/{poolid}` | [delete_pool_deprecated](endpoints/DELETE_pools_poolid.md) | +| GET | `/pools/{poolid}` | [read_pool](endpoints/GET_pools_poolid.md) | +| PUT | `/pools/{poolid}` | [update_pool_deprecated](endpoints/PUT_pools_poolid.md) | +| GET | `/storage` | [index](endpoints/GET_storage.md) | +| POST | `/storage` | [create](endpoints/POST_storage.md) | +| DELETE | `/storage/{storage}` | [delete](endpoints/DELETE_storage_storage.md) | +| GET | `/storage/{storage}` | [read](endpoints/GET_storage_storage.md) | +| PUT | `/storage/{storage}` | [update](endpoints/PUT_storage_storage.md) | +| GET | `/version` | [version](endpoints/GET_version.md) | + + +--- + +# /access + +Endpoints in the `/access` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/access` | [index](endpoints/GET_access.md) | +| GET | `/access/acl` | [read_acl](endpoints/GET_access_acl.md) | +| PUT | `/access/acl` | [update_acl](endpoints/PUT_access_acl.md) | +| GET | `/access/domains` | [index](endpoints/GET_access_domains.md) | +| POST | `/access/domains` | [create](endpoints/POST_access_domains.md) | +| DELETE | `/access/domains/{realm}` | [delete](endpoints/DELETE_access_domains_realm.md) | +| GET | `/access/domains/{realm}` | [read](endpoints/GET_access_domains_realm.md) | +| PUT | `/access/domains/{realm}` | [update](endpoints/PUT_access_domains_realm.md) | +| POST | `/access/domains/{realm}/sync` | [sync](endpoints/POST_access_domains_realm_sync.md) | +| GET | `/access/groups` | [index](endpoints/GET_access_groups.md) | +| POST | `/access/groups` | [create_group](endpoints/POST_access_groups.md) | +| DELETE | `/access/groups/{groupid}` | [delete_group](endpoints/DELETE_access_groups_groupid.md) | +| GET | `/access/groups/{groupid}` | [read_group](endpoints/GET_access_groups_groupid.md) | +| PUT | `/access/groups/{groupid}` | [update_group](endpoints/PUT_access_groups_groupid.md) | +| GET | `/access/openid` | [index](endpoints/GET_access_openid.md) | +| POST | `/access/openid/auth-url` | [auth_url](endpoints/POST_access_openid_auth_url.md) | +| POST | `/access/openid/login` | [login](endpoints/POST_access_openid_login.md) | +| PUT | `/access/password` | [change_password](endpoints/PUT_access_password.md) | +| GET | `/access/permissions` | [permissions](endpoints/GET_access_permissions.md) | +| GET | `/access/roles` | [index](endpoints/GET_access_roles.md) | +| POST | `/access/roles` | [create_role](endpoints/POST_access_roles.md) | +| DELETE | `/access/roles/{roleid}` | [delete_role](endpoints/DELETE_access_roles_roleid.md) | +| GET | `/access/roles/{roleid}` | [read_role](endpoints/GET_access_roles_roleid.md) | +| PUT | `/access/roles/{roleid}` | [update_role](endpoints/PUT_access_roles_roleid.md) | +| GET | `/access/tfa` | [list_tfa](endpoints/GET_access_tfa.md) | +| GET | `/access/tfa/{userid}` | [list_user_tfa](endpoints/GET_access_tfa_userid.md) | +| POST | `/access/tfa/{userid}` | [add_tfa_entry](endpoints/POST_access_tfa_userid.md) | +| DELETE | `/access/tfa/{userid}/{id}` | [delete_tfa](endpoints/DELETE_access_tfa_userid_id.md) | +| GET | `/access/tfa/{userid}/{id}` | [get_tfa_entry](endpoints/GET_access_tfa_userid_id.md) | +| PUT | `/access/tfa/{userid}/{id}` | [update_tfa_entry](endpoints/PUT_access_tfa_userid_id.md) | +| GET | `/access/ticket` | [get_ticket](endpoints/GET_access_ticket.md) | +| POST | `/access/ticket` | [create_ticket](endpoints/POST_access_ticket.md) | +| GET | `/access/users` | [index](endpoints/GET_access_users.md) | +| POST | `/access/users` | [create_user](endpoints/POST_access_users.md) | +| DELETE | `/access/users/{userid}` | [delete_user](endpoints/DELETE_access_users_userid.md) | +| GET | `/access/users/{userid}` | [read_user](endpoints/GET_access_users_userid.md) | +| PUT | `/access/users/{userid}` | [update_user](endpoints/PUT_access_users_userid.md) | +| GET | `/access/users/{userid}/tfa` | [read_user_tfa_type](endpoints/GET_access_users_userid_tfa.md) | +| GET | `/access/users/{userid}/token` | [token_index](endpoints/GET_access_users_userid_token.md) | +| DELETE | `/access/users/{userid}/token/{tokenid}` | [remove_token](endpoints/DELETE_access_users_userid_token_tokenid.md) | +| GET | `/access/users/{userid}/token/{tokenid}` | [read_token](endpoints/GET_access_users_userid_token_tokenid.md) | +| POST | `/access/users/{userid}/token/{tokenid}` | [generate_token](endpoints/POST_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/token/{tokenid}` | [update_token_info](endpoints/PUT_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/unlock-tfa` | [unlock_tfa](endpoints/PUT_access_users_userid_unlock_tfa.md) | +| POST | `/access/vncticket` | [verify_vnc_ticket](endpoints/POST_access_vncticket.md) | + + +--- + +# /cluster + +Endpoints in the `/cluster` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/cluster` | [index](endpoints/GET_cluster.md) | +| GET | `/cluster/acme` | [index](endpoints/GET_cluster_acme.md) | +| GET | `/cluster/acme/account` | [account_index](endpoints/GET_cluster_acme_account.md) | +| POST | `/cluster/acme/account` | [register_account](endpoints/POST_cluster_acme_account.md) | +| DELETE | `/cluster/acme/account/{name}` | [deactivate_account](endpoints/DELETE_cluster_acme_account_name.md) | +| GET | `/cluster/acme/account/{name}` | [get_account](endpoints/GET_cluster_acme_account_name.md) | +| PUT | `/cluster/acme/account/{name}` | [update_account](endpoints/PUT_cluster_acme_account_name.md) | +| GET | `/cluster/acme/challenge-schema` | [challengeschema](endpoints/GET_cluster_acme_challenge_schema.md) | +| GET | `/cluster/acme/directories` | [get_directories](endpoints/GET_cluster_acme_directories.md) | +| GET | `/cluster/acme/meta` | [get_meta](endpoints/GET_cluster_acme_meta.md) | +| GET | `/cluster/acme/plugins` | [index](endpoints/GET_cluster_acme_plugins.md) | +| POST | `/cluster/acme/plugins` | [add_plugin](endpoints/POST_cluster_acme_plugins.md) | +| DELETE | `/cluster/acme/plugins/{id}` | [delete_plugin](endpoints/DELETE_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/plugins/{id}` | [get_plugin_config](endpoints/GET_cluster_acme_plugins_id.md) | +| PUT | `/cluster/acme/plugins/{id}` | [update_plugin](endpoints/PUT_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/tos` | [get_tos](endpoints/GET_cluster_acme_tos.md) | +| GET | `/cluster/backup` | [index](endpoints/GET_cluster_backup.md) | +| POST | `/cluster/backup` | [create_job](endpoints/POST_cluster_backup.md) | +| GET | `/cluster/backup-info` | [index](endpoints/GET_cluster_backup_info.md) | +| GET | `/cluster/backup-info/not-backed-up` | [get_guests_not_in_backup](endpoints/GET_cluster_backup_info_not_backed_up.md) | +| DELETE | `/cluster/backup/{id}` | [delete_job](endpoints/DELETE_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}` | [read_job](endpoints/GET_cluster_backup_id.md) | +| PUT | `/cluster/backup/{id}` | [update_job](endpoints/PUT_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}/included_volumes` | [get_volume_backup_included](endpoints/GET_cluster_backup_id_included_volumes.md) | +| GET | `/cluster/bulk-action` | [index](endpoints/GET_cluster_bulk_action.md) | +| GET | `/cluster/bulk-action/guest` | [index](endpoints/GET_cluster_bulk_action_guest.md) | +| POST | `/cluster/bulk-action/guest/migrate` | [migrate](endpoints/POST_cluster_bulk_action_guest_migrate.md) | +| POST | `/cluster/bulk-action/guest/shutdown` | [shutdown](endpoints/POST_cluster_bulk_action_guest_shutdown.md) | +| POST | `/cluster/bulk-action/guest/start` | [start](endpoints/POST_cluster_bulk_action_guest_start.md) | +| POST | `/cluster/bulk-action/guest/suspend` | [suspend](endpoints/POST_cluster_bulk_action_guest_suspend.md) | +| GET | `/cluster/ceph` | [cephindex](endpoints/GET_cluster_ceph.md) | +| GET | `/cluster/ceph/flags` | [get_all_flags](endpoints/GET_cluster_ceph_flags.md) | +| PUT | `/cluster/ceph/flags` | [set_flags](endpoints/PUT_cluster_ceph_flags.md) | +| GET | `/cluster/ceph/flags/{flag}` | [get_flag](endpoints/GET_cluster_ceph_flags_flag.md) | +| PUT | `/cluster/ceph/flags/{flag}` | [update_flag](endpoints/PUT_cluster_ceph_flags_flag.md) | +| GET | `/cluster/ceph/metadata` | [metadata](endpoints/GET_cluster_ceph_metadata.md) | +| GET | `/cluster/ceph/status` | [status](endpoints/GET_cluster_ceph_status.md) | +| GET | `/cluster/config` | [index](endpoints/GET_cluster_config.md) | +| POST | `/cluster/config` | [create](endpoints/POST_cluster_config.md) | +| GET | `/cluster/config/apiversion` | [join_api_version](endpoints/GET_cluster_config_apiversion.md) | +| GET | `/cluster/config/join` | [join_info](endpoints/GET_cluster_config_join.md) | +| POST | `/cluster/config/join` | [join](endpoints/POST_cluster_config_join.md) | +| GET | `/cluster/config/nodes` | [nodes](endpoints/GET_cluster_config_nodes.md) | +| DELETE | `/cluster/config/nodes/{node}` | [delnode](endpoints/DELETE_cluster_config_nodes_node.md) | +| POST | `/cluster/config/nodes/{node}` | [addnode](endpoints/POST_cluster_config_nodes_node.md) | +| GET | `/cluster/config/qdevice` | [status](endpoints/GET_cluster_config_qdevice.md) | +| GET | `/cluster/config/totem` | [totem](endpoints/GET_cluster_config_totem.md) | +| GET | `/cluster/firewall` | [index](endpoints/GET_cluster_firewall.md) | +| GET | `/cluster/firewall/aliases` | [get_aliases](endpoints/GET_cluster_firewall_aliases.md) | +| POST | `/cluster/firewall/aliases` | [create_alias](endpoints/POST_cluster_firewall_aliases.md) | +| DELETE | `/cluster/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/aliases/{name}` | [read_alias](endpoints/GET_cluster_firewall_aliases_name.md) | +| PUT | `/cluster/firewall/aliases/{name}` | [update_alias](endpoints/PUT_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/groups` | [list_security_groups](endpoints/GET_cluster_firewall_groups.md) | +| POST | `/cluster/firewall/groups` | [create_security_group](endpoints/POST_cluster_firewall_groups.md) | +| DELETE | `/cluster/firewall/groups/{group}` | [delete_security_group](endpoints/DELETE_cluster_firewall_groups_group.md) | +| GET | `/cluster/firewall/groups/{group}` | [get_rules](endpoints/GET_cluster_firewall_groups_group.md) | +| POST | `/cluster/firewall/groups/{group}` | [create_rule](endpoints/POST_cluster_firewall_groups_group.md) | +| DELETE | `/cluster/firewall/groups/{group}/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/groups/{group}/{pos}` | [get_rule](endpoints/GET_cluster_firewall_groups_group_pos.md) | +| PUT | `/cluster/firewall/groups/{group}/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/ipset` | [ipset_index](endpoints/GET_cluster_firewall_ipset.md) | +| POST | `/cluster/firewall/ipset` | [create_ipset](endpoints/POST_cluster_firewall_ipset.md) | +| DELETE | `/cluster/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_cluster_firewall_ipset_name.md) | +| GET | `/cluster/firewall/ipset/{name}` | [get_ipset](endpoints/GET_cluster_firewall_ipset_name.md) | +| POST | `/cluster/firewall/ipset/{name}` | [create_ip](endpoints/POST_cluster_firewall_ipset_name.md) | +| DELETE | `/cluster/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_cluster_firewall_ipset_name_cidr.md) | +| PUT | `/cluster/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/macros` | [get_macros](endpoints/GET_cluster_firewall_macros.md) | +| GET | `/cluster/firewall/options` | [get_options](endpoints/GET_cluster_firewall_options.md) | +| PUT | `/cluster/firewall/options` | [set_options](endpoints/PUT_cluster_firewall_options.md) | +| GET | `/cluster/firewall/refs` | [refs](endpoints/GET_cluster_firewall_refs.md) | +| GET | `/cluster/firewall/rules` | [get_rules](endpoints/GET_cluster_firewall_rules.md) | +| POST | `/cluster/firewall/rules` | [create_rule](endpoints/POST_cluster_firewall_rules.md) | +| DELETE | `/cluster/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_rules_pos.md) | +| GET | `/cluster/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_firewall_rules_pos.md) | +| PUT | `/cluster/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_rules_pos.md) | +| GET | `/cluster/ha` | [index](endpoints/GET_cluster_ha.md) | +| GET | `/cluster/ha/groups` | [index](endpoints/GET_cluster_ha_groups.md) | +| POST | `/cluster/ha/groups` | [create](endpoints/POST_cluster_ha_groups.md) | +| DELETE | `/cluster/ha/groups/{group}` | [delete](endpoints/DELETE_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/groups/{group}` | [read](endpoints/GET_cluster_ha_groups_group.md) | +| PUT | `/cluster/ha/groups/{group}` | [update](endpoints/PUT_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/resources` | [index](endpoints/GET_cluster_ha_resources.md) | +| POST | `/cluster/ha/resources` | [create](endpoints/POST_cluster_ha_resources.md) | +| DELETE | `/cluster/ha/resources/{sid}` | [delete](endpoints/DELETE_cluster_ha_resources_sid.md) | +| GET | `/cluster/ha/resources/{sid}` | [read](endpoints/GET_cluster_ha_resources_sid.md) | +| PUT | `/cluster/ha/resources/{sid}` | [update](endpoints/PUT_cluster_ha_resources_sid.md) | +| POST | `/cluster/ha/resources/{sid}/migrate` | [migrate](endpoints/POST_cluster_ha_resources_sid_migrate.md) | +| POST | `/cluster/ha/resources/{sid}/relocate` | [relocate](endpoints/POST_cluster_ha_resources_sid_relocate.md) | +| GET | `/cluster/ha/rules` | [index](endpoints/GET_cluster_ha_rules.md) | +| POST | `/cluster/ha/rules` | [create_rule](endpoints/POST_cluster_ha_rules.md) | +| DELETE | `/cluster/ha/rules/{rule}` | [delete_rule](endpoints/DELETE_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/rules/{rule}` | [read_rule](endpoints/GET_cluster_ha_rules_rule.md) | +| PUT | `/cluster/ha/rules/{rule}` | [update_rule](endpoints/PUT_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/status` | [index](endpoints/GET_cluster_ha_status.md) | +| POST | `/cluster/ha/status/arm-ha` | [arm-ha](endpoints/POST_cluster_ha_status_arm_ha.md) | +| GET | `/cluster/ha/status/current` | [status](endpoints/GET_cluster_ha_status_current.md) | +| POST | `/cluster/ha/status/disarm-ha` | [disarm-ha](endpoints/POST_cluster_ha_status_disarm_ha.md) | +| GET | `/cluster/ha/status/manager_status` | [manager_status](endpoints/GET_cluster_ha_status_manager_status.md) | +| GET | `/cluster/jobs` | [index](endpoints/GET_cluster_jobs.md) | +| GET | `/cluster/jobs/realm-sync` | [syncjob_index](endpoints/GET_cluster_jobs_realm_sync.md) | +| DELETE | `/cluster/jobs/realm-sync/{id}` | [delete_job](endpoints/DELETE_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/realm-sync/{id}` | [read_job](endpoints/GET_cluster_jobs_realm_sync_id.md) | +| POST | `/cluster/jobs/realm-sync/{id}` | [create_job](endpoints/POST_cluster_jobs_realm_sync_id.md) | +| PUT | `/cluster/jobs/realm-sync/{id}` | [update_job](endpoints/PUT_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/schedule-analyze` | [schedule-analyze](endpoints/GET_cluster_jobs_schedule_analyze.md) | +| GET | `/cluster/log` | [log](endpoints/GET_cluster_log.md) | +| GET | `/cluster/mapping` | [index](endpoints/GET_cluster_mapping.md) | +| GET | `/cluster/mapping/dir` | [index](endpoints/GET_cluster_mapping_dir.md) | +| POST | `/cluster/mapping/dir` | [create](endpoints/POST_cluster_mapping_dir.md) | +| DELETE | `/cluster/mapping/dir/{id}` | [delete](endpoints/DELETE_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/dir/{id}` | [get](endpoints/GET_cluster_mapping_dir_id.md) | +| PUT | `/cluster/mapping/dir/{id}` | [update](endpoints/PUT_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/pci` | [index](endpoints/GET_cluster_mapping_pci.md) | +| POST | `/cluster/mapping/pci` | [create](endpoints/POST_cluster_mapping_pci.md) | +| DELETE | `/cluster/mapping/pci/{id}` | [delete](endpoints/DELETE_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/pci/{id}` | [get](endpoints/GET_cluster_mapping_pci_id.md) | +| PUT | `/cluster/mapping/pci/{id}` | [update](endpoints/PUT_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/usb` | [index](endpoints/GET_cluster_mapping_usb.md) | +| POST | `/cluster/mapping/usb` | [create](endpoints/POST_cluster_mapping_usb.md) | +| DELETE | `/cluster/mapping/usb/{id}` | [delete](endpoints/DELETE_cluster_mapping_usb_id.md) | +| GET | `/cluster/mapping/usb/{id}` | [get](endpoints/GET_cluster_mapping_usb_id.md) | +| PUT | `/cluster/mapping/usb/{id}` | [update](endpoints/PUT_cluster_mapping_usb_id.md) | +| GET | `/cluster/metrics` | [index](endpoints/GET_cluster_metrics.md) | +| GET | `/cluster/metrics/export` | [export](endpoints/GET_cluster_metrics_export.md) | +| GET | `/cluster/metrics/server` | [server_index](endpoints/GET_cluster_metrics_server.md) | +| DELETE | `/cluster/metrics/server/{id}` | [delete](endpoints/DELETE_cluster_metrics_server_id.md) | +| GET | `/cluster/metrics/server/{id}` | [read](endpoints/GET_cluster_metrics_server_id.md) | +| POST | `/cluster/metrics/server/{id}` | [create](endpoints/POST_cluster_metrics_server_id.md) | +| PUT | `/cluster/metrics/server/{id}` | [update](endpoints/PUT_cluster_metrics_server_id.md) | +| GET | `/cluster/nextid` | [nextid](endpoints/GET_cluster_nextid.md) | +| GET | `/cluster/notifications` | [index](endpoints/GET_cluster_notifications.md) | +| GET | `/cluster/notifications/endpoints` | [endpoints_index](endpoints/GET_cluster_notifications_endpoints.md) | +| GET | `/cluster/notifications/endpoints/gotify` | [get_gotify_endpoints](endpoints/GET_cluster_notifications_endpoints_gotify.md) | +| POST | `/cluster/notifications/endpoints/gotify` | [create_gotify_endpoint](endpoints/POST_cluster_notifications_endpoints_gotify.md) | +| DELETE | `/cluster/notifications/endpoints/gotify/{name}` | [delete_gotify_endpoint](endpoints/DELETE_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/gotify/{name}` | [get_gotify_endpoint](endpoints/GET_cluster_notifications_endpoints_gotify_name.md) | +| PUT | `/cluster/notifications/endpoints/gotify/{name}` | [update_gotify_endpoint](endpoints/PUT_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail` | [get_sendmail_endpoints](endpoints/GET_cluster_notifications_endpoints_sendmail.md) | +| POST | `/cluster/notifications/endpoints/sendmail` | [create_sendmail_endpoint](endpoints/POST_cluster_notifications_endpoints_sendmail.md) | +| DELETE | `/cluster/notifications/endpoints/sendmail/{name}` | [delete_sendmail_endpoint](endpoints/DELETE_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail/{name}` | [get_sendmail_endpoint](endpoints/GET_cluster_notifications_endpoints_sendmail_name.md) | +| PUT | `/cluster/notifications/endpoints/sendmail/{name}` | [update_sendmail_endpoint](endpoints/PUT_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/smtp` | [get_smtp_endpoints](endpoints/GET_cluster_notifications_endpoints_smtp.md) | +| POST | `/cluster/notifications/endpoints/smtp` | [create_smtp_endpoint](endpoints/POST_cluster_notifications_endpoints_smtp.md) | +| DELETE | `/cluster/notifications/endpoints/smtp/{name}` | [delete_smtp_endpoint](endpoints/DELETE_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/smtp/{name}` | [get_smtp_endpoint](endpoints/GET_cluster_notifications_endpoints_smtp_name.md) | +| PUT | `/cluster/notifications/endpoints/smtp/{name}` | [update_smtp_endpoint](endpoints/PUT_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/webhook` | [get_webhook_endpoints](endpoints/GET_cluster_notifications_endpoints_webhook.md) | +| POST | `/cluster/notifications/endpoints/webhook` | [create_webhook_endpoint](endpoints/POST_cluster_notifications_endpoints_webhook.md) | +| DELETE | `/cluster/notifications/endpoints/webhook/{name}` | [delete_webhook_endpoint](endpoints/DELETE_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/endpoints/webhook/{name}` | [get_webhook_endpoint](endpoints/GET_cluster_notifications_endpoints_webhook_name.md) | +| PUT | `/cluster/notifications/endpoints/webhook/{name}` | [update_webhook_endpoint](endpoints/PUT_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/matcher-field-values` | [get_matcher_field_values](endpoints/GET_cluster_notifications_matcher_field_values.md) | +| GET | `/cluster/notifications/matcher-fields` | [get_matcher_fields](endpoints/GET_cluster_notifications_matcher_fields.md) | +| GET | `/cluster/notifications/matchers` | [get_matchers](endpoints/GET_cluster_notifications_matchers.md) | +| POST | `/cluster/notifications/matchers` | [create_matcher](endpoints/POST_cluster_notifications_matchers.md) | +| DELETE | `/cluster/notifications/matchers/{name}` | [delete_matcher](endpoints/DELETE_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/matchers/{name}` | [get_matcher](endpoints/GET_cluster_notifications_matchers_name.md) | +| PUT | `/cluster/notifications/matchers/{name}` | [update_matcher](endpoints/PUT_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/targets` | [get_all_targets](endpoints/GET_cluster_notifications_targets.md) | +| POST | `/cluster/notifications/targets/{name}/test` | [test_target](endpoints/POST_cluster_notifications_targets_name_test.md) | +| GET | `/cluster/options` | [get_options](endpoints/GET_cluster_options.md) | +| PUT | `/cluster/options` | [set_options](endpoints/PUT_cluster_options.md) | +| GET | `/cluster/qemu` | [index](endpoints/GET_cluster_qemu.md) | +| GET | `/cluster/qemu/cpu-flags` | [index](endpoints/GET_cluster_qemu_cpu_flags.md) | +| GET | `/cluster/qemu/custom-cpu-models` | [config](endpoints/GET_cluster_qemu_custom_cpu_models.md) | +| POST | `/cluster/qemu/custom-cpu-models` | [create](endpoints/POST_cluster_qemu_custom_cpu_models.md) | +| DELETE | `/cluster/qemu/custom-cpu-models/{cputype}` | [delete](endpoints/DELETE_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/qemu/custom-cpu-models/{cputype}` | [info](endpoints/GET_cluster_qemu_custom_cpu_models_cputype.md) | +| PUT | `/cluster/qemu/custom-cpu-models/{cputype}` | [update](endpoints/PUT_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/replication` | [index](endpoints/GET_cluster_replication.md) | +| POST | `/cluster/replication` | [create](endpoints/POST_cluster_replication.md) | +| DELETE | `/cluster/replication/{id}` | [delete](endpoints/DELETE_cluster_replication_id.md) | +| GET | `/cluster/replication/{id}` | [read](endpoints/GET_cluster_replication_id.md) | +| PUT | `/cluster/replication/{id}` | [update](endpoints/PUT_cluster_replication_id.md) | +| GET | `/cluster/resources` | [resources](endpoints/GET_cluster_resources.md) | +| GET | `/cluster/sdn` | [index](endpoints/GET_cluster_sdn.md) | +| PUT | `/cluster/sdn` | [reload](endpoints/PUT_cluster_sdn.md) | +| GET | `/cluster/sdn/controllers` | [index](endpoints/GET_cluster_sdn_controllers.md) | +| POST | `/cluster/sdn/controllers` | [create](endpoints/POST_cluster_sdn_controllers.md) | +| DELETE | `/cluster/sdn/controllers/{controller}` | [delete](endpoints/DELETE_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/controllers/{controller}` | [read](endpoints/GET_cluster_sdn_controllers_controller.md) | +| PUT | `/cluster/sdn/controllers/{controller}` | [update](endpoints/PUT_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/dns` | [index](endpoints/GET_cluster_sdn_dns.md) | +| POST | `/cluster/sdn/dns` | [create](endpoints/POST_cluster_sdn_dns.md) | +| DELETE | `/cluster/sdn/dns/{dns}` | [delete](endpoints/DELETE_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dns/{dns}` | [read](endpoints/GET_cluster_sdn_dns_dns.md) | +| PUT | `/cluster/sdn/dns/{dns}` | [update](endpoints/PUT_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dry-run` | [dry-run](endpoints/GET_cluster_sdn_dry_run.md) | +| GET | `/cluster/sdn/fabrics` | [index](endpoints/GET_cluster_sdn_fabrics.md) | +| GET | `/cluster/sdn/fabrics/all` | [list_all](endpoints/GET_cluster_sdn_fabrics_all.md) | +| GET | `/cluster/sdn/fabrics/fabric` | [index](endpoints/GET_cluster_sdn_fabrics_fabric.md) | +| POST | `/cluster/sdn/fabrics/fabric` | [add_fabric](endpoints/POST_cluster_sdn_fabrics_fabric.md) | +| DELETE | `/cluster/sdn/fabrics/fabric/{id}` | [delete_fabric](endpoints/DELETE_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/fabric/{id}` | [get_fabric](endpoints/GET_cluster_sdn_fabrics_fabric_id.md) | +| PUT | `/cluster/sdn/fabrics/fabric/{id}` | [update_fabric](endpoints/PUT_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/node` | [list_nodes](endpoints/GET_cluster_sdn_fabrics_node.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}` | [list_nodes_fabric](endpoints/GET_cluster_sdn_fabrics_node_fabric_id.md) | +| POST | `/cluster/sdn/fabrics/node/{fabric_id}` | [add_node](endpoints/POST_cluster_sdn_fabrics_node_fabric_id.md) | +| DELETE | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [delete_node](endpoints/DELETE_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [get_node](endpoints/GET_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| PUT | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [update_node](endpoints/PUT_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/ipams` | [index](endpoints/GET_cluster_sdn_ipams.md) | +| POST | `/cluster/sdn/ipams` | [create](endpoints/POST_cluster_sdn_ipams.md) | +| DELETE | `/cluster/sdn/ipams/{ipam}` | [delete](endpoints/DELETE_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}` | [read](endpoints/GET_cluster_sdn_ipams_ipam.md) | +| PUT | `/cluster/sdn/ipams/{ipam}` | [update](endpoints/PUT_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}/status` | [ipamindex](endpoints/GET_cluster_sdn_ipams_ipam_status.md) | +| DELETE | `/cluster/sdn/lock` | [release_lock](endpoints/DELETE_cluster_sdn_lock.md) | +| POST | `/cluster/sdn/lock` | [lock](endpoints/POST_cluster_sdn_lock.md) | +| GET | `/cluster/sdn/prefix-lists` | [list_prefix_lists](endpoints/GET_cluster_sdn_prefix_lists.md) | +| POST | `/cluster/sdn/prefix-lists` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}` | [delete_prefix_list](endpoints/DELETE_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}` | [get_prefix_list](endpoints/GET_cluster_sdn_prefix_lists_id.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}` | [update_prefix_list](endpoints/PUT_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries` | [get_prefix_list_entries](endpoints/GET_cluster_sdn_prefix_lists_id_entries.md) | +| POST | `/cluster/sdn/prefix-lists/{id}/entries` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists_id_entries.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [delete_prefix_list_entry](endpoints/DELETE_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [get_prefix_list_entry](endpoints/GET_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [update_prefix_list_entry](endpoints/PUT_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| POST | `/cluster/sdn/rollback` | [rollback](endpoints/POST_cluster_sdn_rollback.md) | +| GET | `/cluster/sdn/route-maps` | [list_route_maps](endpoints/GET_cluster_sdn_route_maps.md) | +| GET | `/cluster/sdn/route-maps/entries` | [list_route_map_entries](endpoints/GET_cluster_sdn_route_maps_entries.md) | +| POST | `/cluster/sdn/route-maps/entries` | [create_route_map_entry](endpoints/POST_cluster_sdn_route_maps_entries.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}` | [list_route_map_entries_for_route_map](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id.md) | +| DELETE | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [delete_route_map_entry](endpoints/DELETE_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [get_route_map_entry](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| PUT | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [update_route_map_entry](endpoints/PUT_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/vnets` | [index](endpoints/GET_cluster_sdn_vnets.md) | +| POST | `/cluster/sdn/vnets` | [create](endpoints/POST_cluster_sdn_vnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall` | [index](endpoints/GET_cluster_sdn_vnets_vnet_firewall.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/options` | [get_options](endpoints/GET_cluster_sdn_vnets_vnet_firewall_options.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/options` | [set_options](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_options.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [get_rules](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules.md) | +| POST | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [create_rule](endpoints/POST_cluster_sdn_vnets_vnet_firewall_rules.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/ips` | [ipdelete](endpoints/DELETE_cluster_sdn_vnets_vnet_ips.md) | +| POST | `/cluster/sdn/vnets/{vnet}/ips` | [ipcreate](endpoints/POST_cluster_sdn_vnets_vnet_ips.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/ips` | [ipupdate](endpoints/PUT_cluster_sdn_vnets_vnet_ips.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets` | [index](endpoints/GET_cluster_sdn_vnets_vnet_subnets.md) | +| POST | `/cluster/sdn/vnets/{vnet}/subnets` | [create](endpoints/POST_cluster_sdn_vnets_vnet_subnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/zones` | [index](endpoints/GET_cluster_sdn_zones.md) | +| POST | `/cluster/sdn/zones` | [create](endpoints/POST_cluster_sdn_zones.md) | +| DELETE | `/cluster/sdn/zones/{zone}` | [delete](endpoints/DELETE_cluster_sdn_zones_zone.md) | +| GET | `/cluster/sdn/zones/{zone}` | [read](endpoints/GET_cluster_sdn_zones_zone.md) | +| PUT | `/cluster/sdn/zones/{zone}` | [update](endpoints/PUT_cluster_sdn_zones_zone.md) | +| GET | `/cluster/status` | [get_status](endpoints/GET_cluster_status.md) | +| GET | `/cluster/tasks` | [tasks](endpoints/GET_cluster_tasks.md) | + + +--- + +# /nodes + +Endpoints in the `/nodes` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/nodes` | [index](endpoints/GET_nodes.md) | +| GET | `/nodes/{node}` | [index](endpoints/GET_nodes_node.md) | +| GET | `/nodes/{node}/aplinfo` | [aplinfo](endpoints/GET_nodes_node_aplinfo.md) | +| POST | `/nodes/{node}/aplinfo` | [apl_download](endpoints/POST_nodes_node_aplinfo.md) | +| GET | `/nodes/{node}/apt` | [index](endpoints/GET_nodes_node_apt.md) | +| GET | `/nodes/{node}/apt/changelog` | [changelog](endpoints/GET_nodes_node_apt_changelog.md) | +| GET | `/nodes/{node}/apt/repositories` | [repositories](endpoints/GET_nodes_node_apt_repositories.md) | +| POST | `/nodes/{node}/apt/repositories` | [change_repository](endpoints/POST_nodes_node_apt_repositories.md) | +| PUT | `/nodes/{node}/apt/repositories` | [add_repository](endpoints/PUT_nodes_node_apt_repositories.md) | +| GET | `/nodes/{node}/apt/update` | [list_updates](endpoints/GET_nodes_node_apt_update.md) | +| POST | `/nodes/{node}/apt/update` | [update_database](endpoints/POST_nodes_node_apt_update.md) | +| GET | `/nodes/{node}/apt/versions` | [versions](endpoints/GET_nodes_node_apt_versions.md) | +| GET | `/nodes/{node}/capabilities` | [index](endpoints/GET_nodes_node_capabilities.md) | +| GET | `/nodes/{node}/capabilities/qemu` | [qemu_caps_index](endpoints/GET_nodes_node_capabilities_qemu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu-flags` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu_flags.md) | +| GET | `/nodes/{node}/capabilities/qemu/machines` | [types](endpoints/GET_nodes_node_capabilities_qemu_machines.md) | +| GET | `/nodes/{node}/capabilities/qemu/migration` | [capabilities](endpoints/GET_nodes_node_capabilities_qemu_migration.md) | +| GET | `/nodes/{node}/ceph` | [index](endpoints/GET_nodes_node_ceph.md) | +| GET | `/nodes/{node}/ceph/cfg` | [index](endpoints/GET_nodes_node_ceph_cfg.md) | +| GET | `/nodes/{node}/ceph/cfg/db` | [db](endpoints/GET_nodes_node_ceph_cfg_db.md) | +| GET | `/nodes/{node}/ceph/cfg/raw` | [raw](endpoints/GET_nodes_node_ceph_cfg_raw.md) | +| GET | `/nodes/{node}/ceph/cfg/value` | [value](endpoints/GET_nodes_node_ceph_cfg_value.md) | +| GET | `/nodes/{node}/ceph/cmd-safety` | [cmd_safety](endpoints/GET_nodes_node_ceph_cmd_safety.md) | +| GET | `/nodes/{node}/ceph/crush` | [crush](endpoints/GET_nodes_node_ceph_crush.md) | +| GET | `/nodes/{node}/ceph/fs` | [index](endpoints/GET_nodes_node_ceph_fs.md) | +| DELETE | `/nodes/{node}/ceph/fs/{name}` | [destroyfs](endpoints/DELETE_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/fs/{name}` | [createfs](endpoints/POST_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/init` | [init](endpoints/POST_nodes_node_ceph_init.md) | +| GET | `/nodes/{node}/ceph/log` | [log](endpoints/GET_nodes_node_ceph_log.md) | +| GET | `/nodes/{node}/ceph/mds` | [index](endpoints/GET_nodes_node_ceph_mds.md) | +| DELETE | `/nodes/{node}/ceph/mds/{name}` | [destroymds](endpoints/DELETE_nodes_node_ceph_mds_name.md) | +| POST | `/nodes/{node}/ceph/mds/{name}` | [createmds](endpoints/POST_nodes_node_ceph_mds_name.md) | +| GET | `/nodes/{node}/ceph/mgr` | [index](endpoints/GET_nodes_node_ceph_mgr.md) | +| DELETE | `/nodes/{node}/ceph/mgr/{id}` | [destroymgr](endpoints/DELETE_nodes_node_ceph_mgr_id.md) | +| POST | `/nodes/{node}/ceph/mgr/{id}` | [createmgr](endpoints/POST_nodes_node_ceph_mgr_id.md) | +| GET | `/nodes/{node}/ceph/mon` | [listmon](endpoints/GET_nodes_node_ceph_mon.md) | +| DELETE | `/nodes/{node}/ceph/mon/{monid}` | [destroymon](endpoints/DELETE_nodes_node_ceph_mon_monid.md) | +| POST | `/nodes/{node}/ceph/mon/{monid}` | [createmon](endpoints/POST_nodes_node_ceph_mon_monid.md) | +| GET | `/nodes/{node}/ceph/osd` | [index](endpoints/GET_nodes_node_ceph_osd.md) | +| POST | `/nodes/{node}/ceph/osd` | [createosd](endpoints/POST_nodes_node_ceph_osd.md) | +| DELETE | `/nodes/{node}/ceph/osd/{osdid}` | [destroyosd](endpoints/DELETE_nodes_node_ceph_osd_osdid.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}` | [osdindex](endpoints/GET_nodes_node_ceph_osd_osdid.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/in` | [in](endpoints/POST_nodes_node_ceph_osd_osdid_in.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/lv-info` | [osdvolume](endpoints/GET_nodes_node_ceph_osd_osdid_lv_info.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/metadata` | [osddetails](endpoints/GET_nodes_node_ceph_osd_osdid_metadata.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/out` | [out](endpoints/POST_nodes_node_ceph_osd_osdid_out.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/scrub` | [scrub](endpoints/POST_nodes_node_ceph_osd_osdid_scrub.md) | +| GET | `/nodes/{node}/ceph/pool` | [lspools](endpoints/GET_nodes_node_ceph_pool.md) | +| POST | `/nodes/{node}/ceph/pool` | [createpool](endpoints/POST_nodes_node_ceph_pool.md) | +| DELETE | `/nodes/{node}/ceph/pool/{name}` | [destroypool](endpoints/DELETE_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}` | [poolindex](endpoints/GET_nodes_node_ceph_pool_name.md) | +| PUT | `/nodes/{node}/ceph/pool/{name}` | [setpool](endpoints/PUT_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}/status` | [getpool](endpoints/GET_nodes_node_ceph_pool_name_status.md) | +| POST | `/nodes/{node}/ceph/restart` | [restart](endpoints/POST_nodes_node_ceph_restart.md) | +| GET | `/nodes/{node}/ceph/rules` | [rules](endpoints/GET_nodes_node_ceph_rules.md) | +| POST | `/nodes/{node}/ceph/start` | [start](endpoints/POST_nodes_node_ceph_start.md) | +| GET | `/nodes/{node}/ceph/status` | [status](endpoints/GET_nodes_node_ceph_status.md) | +| POST | `/nodes/{node}/ceph/stop` | [stop](endpoints/POST_nodes_node_ceph_stop.md) | +| GET | `/nodes/{node}/certificates` | [index](endpoints/GET_nodes_node_certificates.md) | +| GET | `/nodes/{node}/certificates/acme` | [index](endpoints/GET_nodes_node_certificates_acme.md) | +| DELETE | `/nodes/{node}/certificates/acme/certificate` | [revoke_certificate](endpoints/DELETE_nodes_node_certificates_acme_certificate.md) | +| POST | `/nodes/{node}/certificates/acme/certificate` | [new_certificate](endpoints/POST_nodes_node_certificates_acme_certificate.md) | +| PUT | `/nodes/{node}/certificates/acme/certificate` | [renew_certificate](endpoints/PUT_nodes_node_certificates_acme_certificate.md) | +| DELETE | `/nodes/{node}/certificates/custom` | [remove_custom_cert](endpoints/DELETE_nodes_node_certificates_custom.md) | +| POST | `/nodes/{node}/certificates/custom` | [upload_custom_cert](endpoints/POST_nodes_node_certificates_custom.md) | +| GET | `/nodes/{node}/certificates/info` | [info](endpoints/GET_nodes_node_certificates_info.md) | +| GET | `/nodes/{node}/config` | [get_config](endpoints/GET_nodes_node_config.md) | +| PUT | `/nodes/{node}/config` | [set_options](endpoints/PUT_nodes_node_config.md) | +| GET | `/nodes/{node}/disks` | [index](endpoints/GET_nodes_node_disks.md) | +| GET | `/nodes/{node}/disks/directory` | [index](endpoints/GET_nodes_node_disks_directory.md) | +| POST | `/nodes/{node}/disks/directory` | [create](endpoints/POST_nodes_node_disks_directory.md) | +| DELETE | `/nodes/{node}/disks/directory/{name}` | [delete](endpoints/DELETE_nodes_node_disks_directory_name.md) | +| POST | `/nodes/{node}/disks/initgpt` | [initgpt](endpoints/POST_nodes_node_disks_initgpt.md) | +| GET | `/nodes/{node}/disks/list` | [list](endpoints/GET_nodes_node_disks_list.md) | +| GET | `/nodes/{node}/disks/lvm` | [index](endpoints/GET_nodes_node_disks_lvm.md) | +| POST | `/nodes/{node}/disks/lvm` | [create](endpoints/POST_nodes_node_disks_lvm.md) | +| DELETE | `/nodes/{node}/disks/lvm/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvm_name.md) | +| GET | `/nodes/{node}/disks/lvmthin` | [index](endpoints/GET_nodes_node_disks_lvmthin.md) | +| POST | `/nodes/{node}/disks/lvmthin` | [create](endpoints/POST_nodes_node_disks_lvmthin.md) | +| DELETE | `/nodes/{node}/disks/lvmthin/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvmthin_name.md) | +| GET | `/nodes/{node}/disks/smart` | [smart](endpoints/GET_nodes_node_disks_smart.md) | +| PUT | `/nodes/{node}/disks/wipedisk` | [wipe_disk](endpoints/PUT_nodes_node_disks_wipedisk.md) | +| GET | `/nodes/{node}/disks/zfs` | [index](endpoints/GET_nodes_node_disks_zfs.md) | +| POST | `/nodes/{node}/disks/zfs` | [create](endpoints/POST_nodes_node_disks_zfs.md) | +| DELETE | `/nodes/{node}/disks/zfs/{name}` | [delete](endpoints/DELETE_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/disks/zfs/{name}` | [detail](endpoints/GET_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/dns` | [dns](endpoints/GET_nodes_node_dns.md) | +| PUT | `/nodes/{node}/dns` | [update_dns](endpoints/PUT_nodes_node_dns.md) | +| POST | `/nodes/{node}/execute` | [execute](endpoints/POST_nodes_node_execute.md) | +| GET | `/nodes/{node}/firewall` | [index](endpoints/GET_nodes_node_firewall.md) | +| GET | `/nodes/{node}/firewall/log` | [log](endpoints/GET_nodes_node_firewall_log.md) | +| GET | `/nodes/{node}/firewall/options` | [get_options](endpoints/GET_nodes_node_firewall_options.md) | +| PUT | `/nodes/{node}/firewall/options` | [set_options](endpoints/PUT_nodes_node_firewall_options.md) | +| GET | `/nodes/{node}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_firewall_rules.md) | +| POST | `/nodes/{node}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_firewall_rules.md) | +| DELETE | `/nodes/{node}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/hardware` | [index](endpoints/GET_nodes_node_hardware.md) | +| GET | `/nodes/{node}/hardware/pci` | [pci_scan](endpoints/GET_nodes_node_hardware_pci.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}` | [pci_index](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev` | [mdevscan](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping_mdev.md) | +| GET | `/nodes/{node}/hardware/usb` | [usbscan](endpoints/GET_nodes_node_hardware_usb.md) | +| GET | `/nodes/{node}/hosts` | [get_etc_hosts](endpoints/GET_nodes_node_hosts.md) | +| POST | `/nodes/{node}/hosts` | [write_etc_hosts](endpoints/POST_nodes_node_hosts.md) | +| GET | `/nodes/{node}/journal` | [journal](endpoints/GET_nodes_node_journal.md) | +| GET | `/nodes/{node}/lxc` | [vmlist](endpoints/GET_nodes_node_lxc.md) | +| POST | `/nodes/{node}/lxc` | [create_vm](endpoints/POST_nodes_node_lxc.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_lxc_vmid.md) | +| GET | `/nodes/{node}/lxc/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_lxc_vmid.md) | +| POST | `/nodes/{node}/lxc/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_lxc_vmid_clone.md) | +| GET | `/nodes/{node}/lxc/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_lxc_vmid_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_lxc_vmid_config.md) | +| GET | `/nodes/{node}/lxc/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_lxc_vmid_feature.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall` | [index](endpoints/GET_nodes_node_lxc_vmid_firewall.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_lxc_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_lxc_vmid_firewall_log.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_lxc_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_lxc_vmid_firewall_options.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_lxc_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_lxc_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_lxc_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/interfaces` | [ip](endpoints/GET_nodes_node_lxc_vmid_interfaces.md) | +| GET | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/move_volume` | [move_volume](endpoints/POST_nodes_node_lxc_vmid_move_volume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_lxc_vmid_mtunnel.md) | +| GET | `/nodes/{node}/lxc/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_lxc_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/lxc/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_lxc_vmid_pending.md) | +| POST | `/nodes/{node}/lxc/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_lxc_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_lxc_vmid_resize.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_lxc_vmid_rrd.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_lxc_vmid_rrddata.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot` | [list](endpoints/GET_nodes_node_lxc_vmid_snapshot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_lxc_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_lxc_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/lxc/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_lxc_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_lxc_vmid_status.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_lxc_vmid_status_current.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_lxc_vmid_status_reboot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_lxc_vmid_status_resume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_lxc_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_lxc_vmid_status_start.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_lxc_vmid_status_stop.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_lxc_vmid_status_suspend.md) | +| POST | `/nodes/{node}/lxc/{vmid}/template` | [template](endpoints/POST_nodes_node_lxc_vmid_template.md) | +| POST | `/nodes/{node}/lxc/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_lxc_vmid_termproxy.md) | +| POST | `/nodes/{node}/lxc/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_lxc_vmid_vncproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_lxc_vmid_vncwebsocket.md) | +| POST | `/nodes/{node}/migrateall` | [migrateall](endpoints/POST_nodes_node_migrateall.md) | +| GET | `/nodes/{node}/netstat` | [netstat](endpoints/GET_nodes_node_netstat.md) | +| DELETE | `/nodes/{node}/network` | [revert_network_changes](endpoints/DELETE_nodes_node_network.md) | +| GET | `/nodes/{node}/network` | [index](endpoints/GET_nodes_node_network.md) | +| POST | `/nodes/{node}/network` | [create_network](endpoints/POST_nodes_node_network.md) | +| PUT | `/nodes/{node}/network` | [reload_network_config](endpoints/PUT_nodes_node_network.md) | +| DELETE | `/nodes/{node}/network/{iface}` | [delete_network](endpoints/DELETE_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/network/{iface}` | [network_config](endpoints/GET_nodes_node_network_iface.md) | +| PUT | `/nodes/{node}/network/{iface}` | [update_network](endpoints/PUT_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/qemu` | [vmlist](endpoints/GET_nodes_node_qemu.md) | +| POST | `/nodes/{node}/qemu` | [create_vm](endpoints/POST_nodes_node_qemu.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent` | [index](endpoints/GET_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent` | [agent](endpoints/POST_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/exec` | [exec](endpoints/POST_nodes_node_qemu_vmid_agent_exec.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/exec-status` | [exec-status](endpoints/GET_nodes_node_qemu_vmid_agent_exec_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/file-read` | [file-read](endpoints/GET_nodes_node_qemu_vmid_agent_file_read.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/file-write` | [file-write](endpoints/POST_nodes_node_qemu_vmid_agent_file_write.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze` | [fsfreeze-freeze](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_freeze.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status` | [fsfreeze-status](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_status.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw` | [fsfreeze-thaw](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_thaw.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fstrim` | [fstrim](endpoints/POST_nodes_node_qemu_vmid_agent_fstrim.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-fsinfo` | [get-fsinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_fsinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-host-name` | [get-host-name](endpoints/GET_nodes_node_qemu_vmid_agent_get_host_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info` | [get-memory-block-info](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_block_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks` | [get-memory-blocks](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_blocks.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-osinfo` | [get-osinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_osinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-time` | [get-time](endpoints/GET_nodes_node_qemu_vmid_agent_get_time.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-timezone` | [get-timezone](endpoints/GET_nodes_node_qemu_vmid_agent_get_timezone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-users` | [get-users](endpoints/GET_nodes_node_qemu_vmid_agent_get_users.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-vcpus` | [get-vcpus](endpoints/GET_nodes_node_qemu_vmid_agent_get_vcpus.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/info` | [info](endpoints/GET_nodes_node_qemu_vmid_agent_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces` | [network-get-interfaces](endpoints/GET_nodes_node_qemu_vmid_agent_network_get_interfaces.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/ping` | [ping](endpoints/POST_nodes_node_qemu_vmid_agent_ping.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/set-user-password` | [set-user-password](endpoints/POST_nodes_node_qemu_vmid_agent_set_user_password.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/shutdown` | [shutdown](endpoints/POST_nodes_node_qemu_vmid_agent_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-disk` | [suspend-disk](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid` | [suspend-hybrid](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_hybrid.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-ram` | [suspend-ram](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_ram.md) | +| POST | `/nodes/{node}/qemu/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_qemu_vmid_clone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_pending](endpoints/GET_nodes_node_qemu_vmid_cloudinit.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_update](endpoints/PUT_nodes_node_qemu_vmid_cloudinit.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit/dump` | [cloudinit_generated_config_dump](endpoints/GET_nodes_node_qemu_vmid_cloudinit_dump.md) | +| GET | `/nodes/{node}/qemu/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/config` | [update_vm_async](endpoints/POST_nodes_node_qemu_vmid_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/dbus-vmstate` | [dbus_vmstate](endpoints/POST_nodes_node_qemu_vmid_dbus_vmstate.md) | +| GET | `/nodes/{node}/qemu/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_qemu_vmid_feature.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall` | [index](endpoints/GET_nodes_node_qemu_vmid_firewall.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_qemu_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_qemu_vmid_firewall_log.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_qemu_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_qemu_vmid_firewall_options.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_qemu_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_qemu_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_qemu_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/monitor` | [monitor](endpoints/POST_nodes_node_qemu_vmid_monitor.md) | +| POST | `/nodes/{node}/qemu/{vmid}/move_disk` | [move_vm_disk](endpoints/POST_nodes_node_qemu_vmid_move_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_qemu_vmid_mtunnel.md) | +| GET | `/nodes/{node}/qemu/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_qemu_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/qemu/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_qemu_vmid_pending.md) | +| POST | `/nodes/{node}/qemu/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_qemu_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_qemu_vmid_resize.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_qemu_vmid_rrd.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_qemu_vmid_rrddata.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/sendkey` | [vm_sendkey](endpoints/PUT_nodes_node_qemu_vmid_sendkey.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot_list](endpoints/GET_nodes_node_qemu_vmid_snapshot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_qemu_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_qemu_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/qemu/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_qemu_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_qemu_vmid_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_qemu_vmid_status_current.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_qemu_vmid_status_reboot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reset` | [vm_reset](endpoints/POST_nodes_node_qemu_vmid_status_reset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_qemu_vmid_status_resume.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_qemu_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_qemu_vmid_status_start.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_qemu_vmid_status_stop.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_qemu_vmid_status_suspend.md) | +| POST | `/nodes/{node}/qemu/{vmid}/template` | [template](endpoints/POST_nodes_node_qemu_vmid_template.md) | +| POST | `/nodes/{node}/qemu/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_qemu_vmid_termproxy.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/unlink` | [unlink](endpoints/PUT_nodes_node_qemu_vmid_unlink.md) | +| POST | `/nodes/{node}/qemu/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_qemu_vmid_vncproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_qemu_vmid_vncwebsocket.md) | +| GET | `/nodes/{node}/query-oci-repo-tags` | [query_oci_repo_tags](endpoints/GET_nodes_node_query_oci_repo_tags.md) | +| GET | `/nodes/{node}/query-url-metadata` | [query_url_metadata](endpoints/GET_nodes_node_query_url_metadata.md) | +| GET | `/nodes/{node}/replication` | [status](endpoints/GET_nodes_node_replication.md) | +| GET | `/nodes/{node}/replication/{id}` | [index](endpoints/GET_nodes_node_replication_id.md) | +| GET | `/nodes/{node}/replication/{id}/log` | [read_job_log](endpoints/GET_nodes_node_replication_id_log.md) | +| POST | `/nodes/{node}/replication/{id}/schedule_now` | [schedule_now](endpoints/POST_nodes_node_replication_id_schedule_now.md) | +| GET | `/nodes/{node}/replication/{id}/status` | [job_status](endpoints/GET_nodes_node_replication_id_status.md) | +| GET | `/nodes/{node}/report` | [report](endpoints/GET_nodes_node_report.md) | +| GET | `/nodes/{node}/rrd` | [rrd](endpoints/GET_nodes_node_rrd.md) | +| GET | `/nodes/{node}/rrddata` | [rrddata](endpoints/GET_nodes_node_rrddata.md) | +| GET | `/nodes/{node}/scan` | [index](endpoints/GET_nodes_node_scan.md) | +| GET | `/nodes/{node}/scan/cifs` | [cifsscan](endpoints/GET_nodes_node_scan_cifs.md) | +| GET | `/nodes/{node}/scan/iscsi` | [iscsiscan](endpoints/GET_nodes_node_scan_iscsi.md) | +| GET | `/nodes/{node}/scan/lvm` | [lvmscan](endpoints/GET_nodes_node_scan_lvm.md) | +| GET | `/nodes/{node}/scan/lvmthin` | [lvmthinscan](endpoints/GET_nodes_node_scan_lvmthin.md) | +| GET | `/nodes/{node}/scan/nfs` | [nfsscan](endpoints/GET_nodes_node_scan_nfs.md) | +| GET | `/nodes/{node}/scan/pbs` | [pbsscan](endpoints/GET_nodes_node_scan_pbs.md) | +| GET | `/nodes/{node}/scan/zfs` | [zfsscan](endpoints/GET_nodes_node_scan_zfs.md) | +| GET | `/nodes/{node}/sdn` | [sdnindex](endpoints/GET_nodes_node_sdn.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}` | [diridx](endpoints/GET_nodes_node_sdn_fabrics_fabric.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/interfaces` | [interfaces](endpoints/GET_nodes_node_sdn_fabrics_fabric_interfaces.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/neighbors` | [neighbors](endpoints/GET_nodes_node_sdn_fabrics_fabric_neighbors.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/routes` | [routes](endpoints/GET_nodes_node_sdn_fabrics_fabric_routes.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}` | [diridx](endpoints/GET_nodes_node_sdn_vnets_vnet.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}/mac-vrf` | [mac-vrf](endpoints/GET_nodes_node_sdn_vnets_vnet_mac_vrf.md) | +| GET | `/nodes/{node}/sdn/zones` | [index](endpoints/GET_nodes_node_sdn_zones.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}` | [diridx](endpoints/GET_nodes_node_sdn_zones_zone.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/bridges` | [bridges](endpoints/GET_nodes_node_sdn_zones_zone_bridges.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/content` | [index](endpoints/GET_nodes_node_sdn_zones_zone_content.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/ip-vrf` | [ip-vrf](endpoints/GET_nodes_node_sdn_zones_zone_ip_vrf.md) | +| GET | `/nodes/{node}/services` | [index](endpoints/GET_nodes_node_services.md) | +| GET | `/nodes/{node}/services/{service}` | [srvcmdidx](endpoints/GET_nodes_node_services_service.md) | +| POST | `/nodes/{node}/services/{service}/reload` | [service_reload](endpoints/POST_nodes_node_services_service_reload.md) | +| POST | `/nodes/{node}/services/{service}/restart` | [service_restart](endpoints/POST_nodes_node_services_service_restart.md) | +| POST | `/nodes/{node}/services/{service}/start` | [service_start](endpoints/POST_nodes_node_services_service_start.md) | +| GET | `/nodes/{node}/services/{service}/state` | [service_state](endpoints/GET_nodes_node_services_service_state.md) | +| POST | `/nodes/{node}/services/{service}/stop` | [service_stop](endpoints/POST_nodes_node_services_service_stop.md) | +| POST | `/nodes/{node}/spiceshell` | [spiceshell](endpoints/POST_nodes_node_spiceshell.md) | +| POST | `/nodes/{node}/startall` | [startall](endpoints/POST_nodes_node_startall.md) | +| GET | `/nodes/{node}/status` | [status](endpoints/GET_nodes_node_status.md) | +| POST | `/nodes/{node}/status` | [node_cmd](endpoints/POST_nodes_node_status.md) | +| POST | `/nodes/{node}/stopall` | [stopall](endpoints/POST_nodes_node_stopall.md) | +| GET | `/nodes/{node}/storage` | [index](endpoints/GET_nodes_node_storage.md) | +| GET | `/nodes/{node}/storage/{storage}` | [diridx](endpoints/GET_nodes_node_storage_storage.md) | +| GET | `/nodes/{node}/storage/{storage}/content` | [index](endpoints/GET_nodes_node_storage_storage_content.md) | +| POST | `/nodes/{node}/storage/{storage}/content` | [create](endpoints/POST_nodes_node_storage_storage_content.md) | +| DELETE | `/nodes/{node}/storage/{storage}/content/{volume}` | [delete](endpoints/DELETE_nodes_node_storage_storage_content_volume.md) | +| GET | `/nodes/{node}/storage/{storage}/content/{volume}` | [info](endpoints/GET_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/content/{volume}` | [copy](endpoints/POST_nodes_node_storage_storage_content_volume.md) | +| PUT | `/nodes/{node}/storage/{storage}/content/{volume}` | [updateattributes](endpoints/PUT_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/download-url` | [download_url](endpoints/POST_nodes_node_storage_storage_download_url.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/download` | [download](endpoints/GET_nodes_node_storage_storage_file_restore_download.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/list` | [list](endpoints/GET_nodes_node_storage_storage_file_restore_list.md) | +| GET | `/nodes/{node}/storage/{storage}/identity` | [identity](endpoints/GET_nodes_node_storage_storage_identity.md) | +| GET | `/nodes/{node}/storage/{storage}/import-metadata` | [get_import_metadata](endpoints/GET_nodes_node_storage_storage_import_metadata.md) | +| POST | `/nodes/{node}/storage/{storage}/oci-registry-pull` | [oci_registry_pull](endpoints/POST_nodes_node_storage_storage_oci_registry_pull.md) | +| DELETE | `/nodes/{node}/storage/{storage}/prunebackups` | [delete](endpoints/DELETE_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/prunebackups` | [dryrun](endpoints/GET_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/rrd` | [rrd](endpoints/GET_nodes_node_storage_storage_rrd.md) | +| GET | `/nodes/{node}/storage/{storage}/rrddata` | [rrddata](endpoints/GET_nodes_node_storage_storage_rrddata.md) | +| GET | `/nodes/{node}/storage/{storage}/status` | [read_status](endpoints/GET_nodes_node_storage_storage_status.md) | +| POST | `/nodes/{node}/storage/{storage}/upload` | [upload](endpoints/POST_nodes_node_storage_storage_upload.md) | +| DELETE | `/nodes/{node}/subscription` | [delete](endpoints/DELETE_nodes_node_subscription.md) | +| GET | `/nodes/{node}/subscription` | [get](endpoints/GET_nodes_node_subscription.md) | +| POST | `/nodes/{node}/subscription` | [update](endpoints/POST_nodes_node_subscription.md) | +| PUT | `/nodes/{node}/subscription` | [set](endpoints/PUT_nodes_node_subscription.md) | +| POST | `/nodes/{node}/suspendall` | [suspendall](endpoints/POST_nodes_node_suspendall.md) | +| GET | `/nodes/{node}/syslog` | [syslog](endpoints/GET_nodes_node_syslog.md) | +| GET | `/nodes/{node}/tasks` | [node_tasks](endpoints/GET_nodes_node_tasks.md) | +| DELETE | `/nodes/{node}/tasks/{upid}` | [stop_task](endpoints/DELETE_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}` | [upid_index](endpoints/GET_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}/log` | [read_task_log](endpoints/GET_nodes_node_tasks_upid_log.md) | +| GET | `/nodes/{node}/tasks/{upid}/status` | [read_task_status](endpoints/GET_nodes_node_tasks_upid_status.md) | +| POST | `/nodes/{node}/termproxy` | [termproxy](endpoints/POST_nodes_node_termproxy.md) | +| GET | `/nodes/{node}/time` | [time](endpoints/GET_nodes_node_time.md) | +| PUT | `/nodes/{node}/time` | [set_timezone](endpoints/PUT_nodes_node_time.md) | +| GET | `/nodes/{node}/version` | [version](endpoints/GET_nodes_node_version.md) | +| POST | `/nodes/{node}/vncshell` | [vncshell](endpoints/POST_nodes_node_vncshell.md) | +| GET | `/nodes/{node}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_vncwebsocket.md) | +| POST | `/nodes/{node}/vzdump` | [vzdump](endpoints/POST_nodes_node_vzdump.md) | +| GET | `/nodes/{node}/vzdump/defaults` | [defaults](endpoints/GET_nodes_node_vzdump_defaults.md) | +| GET | `/nodes/{node}/vzdump/extractconfig` | [extractconfig](endpoints/GET_nodes_node_vzdump_extractconfig.md) | +| POST | `/nodes/{node}/wakeonlan` | [wakeonlan](endpoints/POST_nodes_node_wakeonlan.md) | + + +--- + +# /pools + +Endpoints in the `/pools` section. + +| Method | Path | Summary | +|---|---|---| +| DELETE | `/pools` | [delete_pool](endpoints/DELETE_pools.md) | +| GET | `/pools` | [index](endpoints/GET_pools.md) | +| POST | `/pools` | [create_pool](endpoints/POST_pools.md) | +| PUT | `/pools` | [update_pool](endpoints/PUT_pools.md) | +| DELETE | `/pools/{poolid}` | [delete_pool_deprecated](endpoints/DELETE_pools_poolid.md) | +| GET | `/pools/{poolid}` | [read_pool](endpoints/GET_pools_poolid.md) | +| PUT | `/pools/{poolid}` | [update_pool_deprecated](endpoints/PUT_pools_poolid.md) | + + +--- + +# /storage + +Endpoints in the `/storage` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/storage` | [index](endpoints/GET_storage.md) | +| POST | `/storage` | [create](endpoints/POST_storage.md) | +| DELETE | `/storage/{storage}` | [delete](endpoints/DELETE_storage_storage.md) | +| GET | `/storage/{storage}` | [read](endpoints/GET_storage_storage.md) | +| PUT | `/storage/{storage}` | [update](endpoints/PUT_storage_storage.md) | + + +--- + +# /version + +Endpoints in the `/version` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/version` | [version](endpoints/GET_version.md) | + + +--- + + + +# GET /access + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/acl + +Get Access Control List (ACLs). + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "The returned list is restricted to objects where you have rights to modify permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /access/acl + +Update Access Control List (add or remove permissions). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| path | string | yes | Access control path | +| roles | string | yes | List of roles. | +| delete | boolean | no | Remove permissions (instead of adding it). | +| groups | string | no | List of groups. | +| propagate | boolean | no | Allow to propagate (inherit) permissions. | +| tokens | string | no | List of API tokens. | +| users | string | no | List of users. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm-modify", + "{path}" + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/domains + +Authentication domain index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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 /access/domains + +Add an authentication server. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | +| type | string | yes | Realm type. | +| acr-values | string | no | Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request. | +| audiences | string | no | A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'. | +| autocreate | boolean | no | Automatically create users if they do not exist. | +| base_dn | string | no | LDAP base domain name | +| bind_dn | string | no | LDAP bind domain name | +| capath | string | no | Path to the CA certificate store | +| case-sensitive | boolean | no | username is case-sensitive | +| cert | string | no | Path to the client certificate | +| certkey | string | no | Path to the client certificate key | +| check-connection | boolean | no | Check bind connection to the server. | +| client-id | string | no | OpenID Client ID | +| client-key | string | no | OpenID Client Key | +| comment | string | no | Description. | +| default | boolean | no | Use this as default realm | +| domain | string | no | AD domain name | +| filter | string | no | LDAP filter for user sync. | +| group_classes | string | no | The objectclasses for groups. | +| group_dn | string | no | LDAP base domain name for group sync. If not set, the base_dn will be used. | +| group_filter | string | no | LDAP filter for group sync. | +| group_name_attr | string | no | LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name. | +| groups-autocreate | boolean | no | Automatically create groups if they do not exist. | +| groups-claim | string | no | OpenID claim used to retrieve groups with. | +| groups-overwrite | boolean | no | All groups will be overwritten for the user on login. | +| issuer-url | string | no | OpenID Issuer Url | +| mode | string | no | LDAP protocol mode. | +| password | string | no | LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'. | +| port | integer | no | Server port. | +| prompt | string | no | Specifies whether the Authorization Server prompts the End-User for reauthentication and consent. | +| query-userinfo | boolean | no | Enables querying the userinfo endpoint for claims values. | +| scopes | string | no | Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'. | +| secure | boolean | no | Use secure LDAPS protocol. DEPRECATED: use 'mode' instead. | +| server1 | string | no | Server IP address (or DNS name) | +| server2 | string | no | Fallback Server IP address (or DNS name) | +| sslversion | string | no | LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! | +| sync_attributes | string | no | 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. | +| sync-defaults-options | string | no | The default options for behavior of synchronizations. | +| tfa | string | no | Use Two-factor authentication. | +| user_attr | string | no | LDAP user attribute name | +| user_classes | string | no | The objectclasses for users. | +| username-claim | string | no | OpenID claim used to generate the unique username. | +| verify | boolean | no | Verify the server's SSL certificate | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /access/domains/{realm} + +Delete an authentication server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/domains/{realm} + +Get auth server configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +None. + +## Returns + +```json +{} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate", + "Sys.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/domains/{realm} + +Update authentication server settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acr-values | string | no | Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request. | +| audiences | string | no | A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'. | +| autocreate | boolean | no | Automatically create users if they do not exist. | +| base_dn | string | no | LDAP base domain name | +| bind_dn | string | no | LDAP bind domain name | +| capath | string | no | Path to the CA certificate store | +| case-sensitive | boolean | no | username is case-sensitive | +| cert | string | no | Path to the client certificate | +| certkey | string | no | Path to the client certificate key | +| check-connection | boolean | no | Check bind connection to the server. | +| client-id | string | no | OpenID Client ID | +| client-key | string | no | OpenID Client Key | +| comment | string | no | Description. | +| default | boolean | no | Use this as default realm | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| domain | string | no | AD domain name | +| filter | string | no | LDAP filter for user sync. | +| group_classes | string | no | The objectclasses for groups. | +| group_dn | string | no | LDAP base domain name for group sync. If not set, the base_dn will be used. | +| group_filter | string | no | LDAP filter for group sync. | +| group_name_attr | string | no | LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name. | +| groups-autocreate | boolean | no | Automatically create groups if they do not exist. | +| groups-claim | string | no | OpenID claim used to retrieve groups with. | +| groups-overwrite | boolean | no | All groups will be overwritten for the user on login. | +| issuer-url | string | no | OpenID Issuer Url | +| mode | string | no | LDAP protocol mode. | +| password | string | no | LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'. | +| port | integer | no | Server port. | +| prompt | string | no | Specifies whether the Authorization Server prompts the End-User for reauthentication and consent. | +| query-userinfo | boolean | no | Enables querying the userinfo endpoint for claims values. | +| scopes | string | no | Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'. | +| secure | boolean | no | Use secure LDAPS protocol. DEPRECATED: use 'mode' instead. | +| server1 | string | no | Server IP address (or DNS name) | +| server2 | string | no | Fallback Server IP address (or DNS name) | +| sslversion | string | no | LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! | +| sync_attributes | string | no | 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. | +| sync-defaults-options | string | no | The default options for behavior of synchronizations. | +| tfa | string | no | Use Two-factor authentication. | +| user_attr | string | no | LDAP user attribute name | +| user_classes | string | no | The objectclasses for users. | +| verify | boolean | no | Verify the server's SSL certificate | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /access/domains/{realm}/sync + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| enable-new | boolean | yes | Enable newly synced users immediately. | +| full | boolean | yes | 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. | +| purge | boolean | yes | DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync. | +| remove-vanished | string | yes | 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). | +| scope | string | yes | Select what to sync. | +| dry-run | boolean | no | If set, does not write anything. | + +## Returns + +```json +{ + "description": "Worker Task-UPID", + "type": "string" +} +``` + +## Permissions + +```json +{ + "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/'." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/groups + +Group index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /access/groups + +Create new group. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /access/groups/{groupid} + +Delete group. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/groups/{groupid} + +Get group configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Sys.Audit", + "Group.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/groups/{groupid} + +Update group data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/openid + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /access/openid/auth-url + +Get the OpenId Authorization Url for the specified realm. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | +| redirect-url | string | yes | Redirection Url. The client should set this to the used server url (location.origin). | + +## Returns + +```json +{ + "description": "Redirection URL.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /access/openid/login + +Verify OpenID authorization code and create a ticket. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| code | string | yes | OpenId authorization code. | +| redirect-url | string | yes | Redirection Url. The client should set this to the used server url (location.origin). | +| state | string | yes | OpenId state. | + +## Returns + +```json +{ + "properties": { + "CSRFPreventionToken": { + "type": "string" + }, + "cap": { + "type": "object" + }, + "clustername": { + "optional": 1, + "type": "string" + }, + "ticket": { + "type": "string" + }, + "username": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# PUT /access/password + +Change user password. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | The new password. | +| userid | string | yes | Full User ID, in the `name@realm` format. | +| confirmation-password | string | no | The current password of the user performing the change. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/permissions + +Retrieve effective permissions of given user/token. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| path | string | no | Only dump this specific path, not the whole tree. | +| userid | string | no | User ID or full API token ID | + +## Returns + +```json +{ + "description": "Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").", + "type": "object" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/roles + +Role index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /access/roles + +Create new role. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | +| privs | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /access/roles/{roleid} + +Delete role. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/roles/{roleid} + +Get role configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /access/roles/{roleid} + +Update an existing role. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| append | boolean | no | | +| privs | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/tfa + +List TFA configurations of users. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Returns all or just the logged-in user, depending on privileges.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/tfa/{userid} + +List TFA configurations of users. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/tfa/{userid} + +Add a TFA entry for a user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | TFA Entry Type. | +| challenge | string | no | When responding to a u2f challenge: the original challenge string | +| description | string | no | A description to distinguish multiple entries from one another | +| password | string | no | The current password of the user performing the change. | +| totp | string | no | A totp URI. | +| value | string | no | The current value for the provided totp URI, or a Webauthn/U2F challenge response | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /access/tfa/{userid}/{id} + +Delete a TFA entry by ID. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | A TFA entry id. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | no | The current password of the user performing the change. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/tfa/{userid}/{id} + +Fetch a requested TFA entry if present. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | A TFA entry id. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/tfa/{userid}/{id} + +Add a TFA entry for a user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | A TFA entry id. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| description | string | no | A description to distinguish multiple entries from one another | +| enable | boolean | no | Whether the entry should be enabled for login. | +| password | string | no | The current password of the user performing the change. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/ticket + +Dummy. Useful for formatters which want to provide a login page. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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 /access/ticket + +Create or verify authentication ticket. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | The secret password. This can also be a valid ticket. | +| username | string | yes | User name | +| new-format | boolean | no | This parameter is now ignored and assumed to be 1. | +| otp | string | no | One-time password for Two-factor authentication. | +| path | string | no | Verify ticket, and check if user have access 'privs' on 'path' | +| privs | string | no | Verify ticket, and check if user have access 'privs' on 'path' | +| realm | string | no | You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @. | +| tfa-challenge | string | no | The signed TFA challenge string the user wants to respond to. | + +## Returns + +```json +{ + "properties": { + "CSRFPreventionToken": { + "optional": 1, + "type": "string" + }, + "clustername": { + "optional": 1, + "type": "string" + }, + "ticket": { + "optional": 1, + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "description": "You need to pass valid credientials.", + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/users + +User index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| enabled | boolean | no | Optional filter for enable property. | +| full | boolean | no | Include group and token information. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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 /access/users + +Create new user. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | +| comment | string | no | | +| email | string | no | | +| enable | boolean | no | Enable the account (default). You can set this to '0' to disable the account | +| expire | integer | no | Account expiration date (seconds since epoch). '0' means no expiration date. | +| firstname | string | no | | +| groups | string | no | | +| keys | string | no | Keys for two factor auth (yubico). | +| lastname | string | no | | +| password | string | no | Initial password. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /access/users/{userid} + +Delete user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/users/{userid} + +Get user configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/users/{userid} + +Update user configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| append | boolean | no | | +| comment | string | no | | +| email | string | no | | +| enable | boolean | no | Enable the account (default). You can set this to '0' to disable the account | +| expire | integer | no | Account expiration date (seconds since epoch). '0' means no expiration date. | +| firstname | string | no | | +| groups | string | no | | +| keys | string | no | Keys for two factor auth (yubico). | +| lastname | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "update" + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/users/{userid}/tfa + +Get user TFA types (Personal and Realm). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| multiple | boolean | no | Request all entries as an array. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /access/users/{userid}/token + +Get user API tokens. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /access/users/{userid}/token/{tokenid} + +Remove API token for a specific user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/users/{userid}/token/{tokenid} + +Get specific API token information. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/users/{userid}/token/{tokenid} + +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! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| expire | integer | no | API token expiration date (seconds since epoch). '0' means no expiration date. | +| privsep | boolean | no | Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /access/users/{userid}/token/{tokenid} + +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! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| delete | string | no | A list of settings you want to delete. | +| expire | integer | no | API token expiration date (seconds since epoch). '0' means no expiration date. | +| privsep | boolean | no | Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user. | +| regenerate | boolean | no | Regenerate the token's secret value. All users of the previous secret will lose access after this operation. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# PUT /access/users/{userid}/unlock-tfa + +Unlock a user's TFA authentication. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "boolean" +} +``` + +## Permissions + +```json +{ + "check": [ + "userid-group", + [ + "User.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /access/vncticket + +verify VNC authentication ticket. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| authid | string | yes | UserId or token | +| path | string | yes | Verify ticket, and check if user have access 'privs' on 'path' | +| privs | string | yes | Verify ticket, and check if user have access 'privs' on 'path' | +| vncticket | string | yes | The VNC ticket. | +| port | integer | no | Verify that the ticket is valid for this port. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "You need to pass valid credientials.", + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster + +Cluster index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/acme + +ACMEAccount index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/acme/account + +ACMEAccount index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/acme/account + +Register a new ACME account with CA. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| contact | string | yes | Contact email addresses. | +| directory | string | no | URL of ACME CA directory endpoint. | +| eab-hmac-key | string | no | HMAC key for External Account Binding. | +| eab-kid | string | no | Key Identifier for External Account Binding. | +| name | string | no | ACME account config file name. | +| tos_url | string | no | URL of CA TermsOfService - setting this indicates agreement. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/acme/account/{name} + +Deactivate existing ACME account at CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | no | ACME account config file name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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 /cluster/acme/account/{name} + +Return existing ACME account information. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | no | ACME account config file name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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 /cluster/acme/account/{name} + +Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | no | ACME account config file name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| contact | string | no | Contact email addresses. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/acme/challenge-schema + +Get schema of ACME challenge types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/acme/directories + +Get named known ACME directory endpoints. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "additionalProperties": 0, + "properties": { + "name": { + "type": "string" + }, + "url": { + "description": "URL of ACME CA directory endpoint.", + "pattern": "^https?://.*", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/acme/meta + +Retrieve ACME Directory Meta Information + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| directory | string | no | URL of ACME CA directory endpoint. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/acme/plugins + +ACME plugin index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list ACME plugins of a specific type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/acme/plugins + +Add ACME plugin configuration. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | ACME Plugin ID name | +| type | string | yes | ACME challenge type. | +| api | string | no | API plugin name | +| data | string | no | DNS plugin data. (base64 encoded) | +| disable | boolean | no | Flag to disable the config. | +| nodes | string | no | List of cluster node names. | +| validation-delay | integer | no | Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/acme/plugins/{id} + +Delete ACME plugin configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Unique identifier for ACME plugin instance. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/acme/plugins/{id} + +Get ACME plugin configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Unique identifier for ACME plugin instance. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/acme/plugins/{id} + +Update ACME plugin configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | ACME Plugin ID name | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| api | string | no | API plugin name | +| data | string | no | DNS plugin data. (base64 encoded) | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable the config. | +| nodes | string | no | List of cluster node names. | +| validation-delay | integer | no | Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/acme/tos + +Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| directory | string | no | URL of ACME CA directory endpoint. | + +## Returns + +```json +{ + "description": "ACME TermsOfService URL.", + "optional": 1, + "type": "string" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/backup + +List vzdump backup schedule. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/backup + +Create new vzdump backup job. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| all | boolean | no | Backup all known guest systems on this host. | +| bwlimit | integer | no | Limit I/O bandwidth (in KiB/s). | +| comment | string | no | Description for the Job. | +| compress | string | no | Compress dump file. | +| dow | string | no | Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| dumpdir | string | no | Store resulting files to specified directory. | +| enabled | boolean | no | Enable or disable the job. | +| exclude | string | no | Exclude specified guest systems (assumes --all) | +| exclude-path | array | no | Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory. | +| fleecing | string | no | Options for backup fleecing (VM only). | +| id | string | no | Job ID (will be autogenerated). | +| ionice | integer | no | 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. | +| lockwait | integer | no | Maximal time to wait for the global lock (minutes). | +| mailnotification | string | no | Deprecated: use notification targets/matchers instead. Specify when to send a notification mail | +| mailto | string | no | Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications. | +| mode | string | no | Backup mode. | +| node | string | no | Only run if executed on this node. | +| notes-template | string | no | 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. | +| notification-mode | string | no | 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. | +| pbs-change-detection-mode | string | no | PBS mode used to detect file changes and switch encoding format for container backups. | +| performance | string | no | Other performance-related settings. | +| pigz | integer | no | Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count. | +| pool | string | no | Backup all known guest systems included in the specified pool. | +| protected | boolean | no | If true, mark backup(s) as protected. | +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| quiet | boolean | no | Be quiet. | +| remove | boolean | no | Prune older backups according to 'prune-backups'. | +| repeat-missed | boolean | no | If true, the job will be run as soon as possible if it was missed while the scheduler was not running. | +| schedule | string | no | Backup schedule. The format is a subset of `systemd` calendar events. | +| script | string | no | Use specified hook script. | +| starttime | string | no | Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| stdexcludes | boolean | no | Exclude temporary files and logs. | +| stop | boolean | no | Stop running backup jobs on this host. | +| stopwait | integer | no | Maximal time to wait until a guest system is stopped (minutes). | +| storage | string | no | Store resulting file to this storage. | +| tmpdir | string | no | Store temporary files to specified directory. | +| vmid | string | no | The ID of the guest system you want to backup. | +| zstd | integer | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/backup-info + +Index for backup info related endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Directory index.", + "items": { + "properties": { + "subdir": { + "description": "API sub-directory endpoint", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/backup-info/not-backed-up + +Shows all guests which are not covered by any backup job. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/backup/{id} + +Delete vzdump backup job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/backup/{id} + +Read vzdump backup job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/backup/{id} + +Update vzdump backup job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| all | boolean | no | Backup all known guest systems on this host. | +| bwlimit | integer | no | Limit I/O bandwidth (in KiB/s). | +| comment | string | no | Description for the Job. | +| compress | string | no | Compress dump file. | +| delete | string | no | A list of settings you want to delete. | +| dow | string | no | Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| dumpdir | string | no | Store resulting files to specified directory. | +| enabled | boolean | no | Enable or disable the job. | +| exclude | string | no | Exclude specified guest systems (assumes --all) | +| exclude-path | array | no | Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory. | +| fleecing | string | no | Options for backup fleecing (VM only). | +| ionice | integer | no | 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. | +| lockwait | integer | no | Maximal time to wait for the global lock (minutes). | +| mailnotification | string | no | Deprecated: use notification targets/matchers instead. Specify when to send a notification mail | +| mailto | string | no | Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications. | +| mode | string | no | Backup mode. | +| node | string | no | Only run if executed on this node. | +| notes-template | string | no | 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. | +| notification-mode | string | no | 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. | +| pbs-change-detection-mode | string | no | PBS mode used to detect file changes and switch encoding format for container backups. | +| performance | string | no | Other performance-related settings. | +| pigz | integer | no | Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count. | +| pool | string | no | Backup all known guest systems included in the specified pool. | +| protected | boolean | no | If true, mark backup(s) as protected. | +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| quiet | boolean | no | Be quiet. | +| remove | boolean | no | Prune older backups according to 'prune-backups'. | +| repeat-missed | boolean | no | If true, the job will be run as soon as possible if it was missed while the scheduler was not running. | +| schedule | string | no | Backup schedule. The format is a subset of `systemd` calendar events. | +| script | string | no | Use specified hook script. | +| starttime | string | no | Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| stdexcludes | boolean | no | Exclude temporary files and logs. | +| stop | boolean | no | Stop running backup jobs on this host. | +| stopwait | integer | no | Maximal time to wait until a guest system is stopped (minutes). | +| storage | string | no | Store resulting file to this storage. | +| tmpdir | string | no | Store temporary files to specified directory. | +| vmid | string | no | The ID of the guest system you want to backup. | +| zstd | integer | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/backup/{id}/included_volumes + +Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/bulk-action + +List resource types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/bulk-action/guest + +Bulk action index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/bulk-action/guest/migrate + +Bulk migrate all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| online | boolean | no | Enable live migration for VMs and restart migration for CTs. | +| vms | array | no | Only consider guests from this list of VMIDs. | +| with-local-disks | boolean | no | Enable live storage migration for local disk | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/bulk-action/guest/shutdown + +Bulk shutdown all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force-stop | boolean | no | Makes sure the Guest stops after the timeout. | +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| timeout | integer | no | Default shutdown timeout in seconds if none is configured for the guest. | +| vms | array | no | Only consider guests from this list of VMIDs. | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/bulk-action/guest/start + +Bulk start or resume all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| timeout | integer | no | Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration). | +| vms | array | no | Only consider guests from this list of VMIDs. | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/bulk-action/guest/suspend + +Bulk suspend all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| statestorage | string | no | The storage for the VM state. | +| to-disk | boolean | no | If set, suspends the guests to disk. Will be resumed on next start. | +| vms | array | no | Only consider guests from this list of VMIDs. | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ceph + +Cluster ceph index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ceph/flags + +get the status of all ceph flags + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ceph/flags + +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. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| nobackfill | boolean | no | Backfilling of PGs is suspended. | +| nodeep-scrub | boolean | no | Deep Scrubbing is disabled. | +| nodown | boolean | no | OSD failure reports are being ignored, such that the monitors will not mark OSDs down. | +| noin | boolean | no | OSDs that were previously marked out will not be marked back in when they start. | +| noout | boolean | no | OSDs will not automatically be marked out after the configured interval. | +| norebalance | boolean | no | Rebalancing of PGs is suspended. | +| norecover | boolean | no | Recovery of PGs is suspended. | +| noscrub | boolean | no | Scrubbing is disabled. | +| notieragent | boolean | no | Cache tiering activity is suspended. | +| noup | boolean | no | OSDs are not allowed to start. | +| pause | boolean | no | Pauses read and writes. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ceph/flags/{flag} + +Get the status of a specific ceph flag. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| flag | string | yes | The name of the flag name to get. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "boolean" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ceph/flags/{flag} + +Set or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| flag | string | yes | The ceph flag to update | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| value | boolean | yes | The new value of the flag | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ceph/metadata + +Get ceph metadata. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| scope | string | no | 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. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ceph/status + +Get ceph status. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/config + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/config + +Generate new cluster configuration. If no links given, default to local IP address as link0. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| clustername | string | yes | The name of the cluster. | +| link[n] | string | no | Address and priority information of a single corosync link. (up to 8 links supported; link0..link7) | +| nodeid | integer | no | Node id for this node. | +| token-coefficient | integer | no | Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details. | +| votes | integer | no | Number of votes for this node. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/config/apiversion + +Return the version of the cluster join API available on this node. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Cluster Join API version, currently 1", + "minimum": 0, + "type": "integer" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/config/join + +Get information needed to join this cluster over the connected node. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | no | The node for which the joinee gets the nodeinfo. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/config/join + +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). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fingerprint | string | yes | Certificate SHA 256 fingerprint. | +| hostname | string | yes | Hostname (or IP) of an existing cluster member. | +| password | string | yes | Superuser (root) password of peer node. | +| force | boolean | no | Do not throw error if node already exists. | +| link[n] | string | no | Address and priority information of a single corosync link. (up to 8 links supported; link0..link7) | +| nodeid | integer | no | Node id for this node. | +| votes | integer | no | Number of votes for this node | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/config/nodes + +Corosync node list. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "node": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{node}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/config/nodes/{node} + +Removes a node from the cluster configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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 /cluster/config/nodes/{node} + +Adds a node to the cluster configuration. This call is for internal use. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| apiversion | integer | no | The JOIN_API_VERSION of the new node. | +| force | boolean | no | Do not throw error if node already exists. | +| link[n] | string | no | Address and priority information of a single corosync link. (up to 8 links supported; link0..link7) | +| new_node_ip | string | no | IP Address of node to add. Used as fallback if no links are given. | +| nodeid | integer | no | Node id for this node. | +| votes | integer | no | Number of votes for this node | + +## Returns + +```json +{ + "properties": { + "corosync_authkey": { + "type": "string" + }, + "corosync_conf": { + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/config/qdevice + +Get QDevice status + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "allowtoken": 1, + "description": "Get QDevice status", + "method": "GET", + "name": "status", + "parameters": { + "additionalProperties": 0 + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected": 1, + "returns": { + "type": "object" + } +} +``` + + +--- + + + +# GET /cluster/config/totem + +Get corosync totem protocol settings. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "allowtoken": 1, + "description": "Get corosync totem protocol settings.", + "method": "GET", + "name": "totem", + "parameters": { + "additionalProperties": 0 + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns": { + "type": "object" + } +} +``` + + +--- + + + +# GET /cluster/firewall + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/firewall/aliases + +List aliases + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/aliases + +Create IP or Network Alias. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | Alias name. | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/firewall/aliases/{name} + +Remove IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/aliases/{name} + +Read alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/aliases/{name} + +Update IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing alias. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/firewall/groups + +List security groups. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/groups + +Create new security group. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/firewall/groups/{group} + +Delete security group. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/groups/{group} + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/groups/{group} + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/firewall/groups/{group}/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/groups/{group}/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/groups/{group}/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/firewall/ipset + +List IPSets + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/ipset + +Create new IPSet + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/firewall/ipset/{name} + +Delete IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Delete all members of the IPSet, if there are any. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/ipset/{name} + +List IPSet content + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/ipset/{name} + +Add IP or Network to IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/firewall/ipset/{name}/{cidr} + +Remove IP or Network from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/ipset/{name}/{cidr} + +Read IP or Network settings from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/ipset/{name}/{cidr} + +Update IP or Network settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/firewall/macros + +List available macros + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "descr": { + "description": "More verbose description (if available).", + "type": "string" + }, + "macro": { + "description": "Macro name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/firewall/options + +Get Firewall options. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/options + +Set Firewall options. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| ebtables | boolean | no | Enable ebtables rules cluster wide. | +| enable | integer | no | Enable or disable the firewall cluster wide. | +| log_ratelimit | string | no | Log ratelimiting settings | +| policy_forward | string | no | Forward policy. | +| policy_in | string | no | Input policy. | +| policy_out | string | no | Output policy. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/firewall/refs + +Lists possible IPSet/Alias reference which are allowed in source/dest properties. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list references of specified type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/firewall/rules + +List rules. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/rules + +Create new rule. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ha + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ha/groups + +Get HA groups. (deprecated in favor of HA rules) + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "group": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{group}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/groups + +Create a new HA group. (deprecated in favor of HA rules) + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | +| nodes | string | yes | List of cluster node names with optional priority. | +| comment | string | no | Description. | +| nofailback | boolean | no | 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. | +| restricted | boolean | no | Resources bound to restricted groups may only run on nodes defined by the group. | +| type | string | no | Group type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/ha/groups/{group} + +Delete ha group configuration. (deprecated in favor of HA rules) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/groups/{group} + +Read ha group configuration. (deprecated in favor of HA rules) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | + +## Request parameters + +None. + +## Returns + +```json +{} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/groups/{group} + +Update ha group configuration. (deprecated in favor of HA rules) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nodes | string | no | List of cluster node names with optional priority. | +| nofailback | boolean | no | 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. | +| restricted | boolean | no | Resources bound to restricted groups may only run on nodes defined by the group. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ha/resources + +List HA resources. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list resources of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "sid": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{sid}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/resources + +Create a new HA resource. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | +| auto-rebalance | boolean | no | HA resource may be migrated during automatic rebalancing | +| comment | string | no | Description. | +| failback | boolean | no | 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. | +| group | string | no | The HA group identifier. | +| max_relocate | integer | no | Maximal number of resource relocate tries when a resource fails to start. | +| max_restart | integer | no | 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. | +| state | string | no | Requested resource state. | +| type | string | no | Resource type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/ha/resources/{sid} + +Delete resource configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| purge | boolean | no | Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/resources/{sid} + +Read resource configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/resources/{sid} + +Update resource configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| auto-rebalance | boolean | no | HA resource may be migrated during automatic rebalancing | +| comment | string | no | Description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| failback | boolean | no | 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. | +| group | string | no | The HA group identifier. | +| max_relocate | integer | no | Maximal number of resource relocate tries when a resource fails to start. | +| max_restart | integer | no | 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. | +| state | string | no | Requested resource state. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/ha/resources/{sid}/migrate + +Request resource migration (online) to another node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/ha/resources/{sid}/relocate + +Request resource relocation to another node. This stops the service on the old node, and restarts it on the target node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ha/rules + +Get HA rules. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| resource | string | no | Limit the returned list to rules affecting the specified resource. | +| type | string | no | Limit the returned list to the specified rule type. | + +## Returns + +```json +{ + "items": { + "links": [ + { + "href": "{rule}", + "rel": "child" + } + ], + "properties": { + "rule": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/rules + +Create HA rule. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| resources | string | yes | 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). | +| rule | string | yes | HA rule identifier. | +| type | string | yes | HA rule type. | +| affinity | string | no | 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'). | +| comment | string | no | HA rule description. | +| disable | boolean | no | Whether the HA rule is disabled. | +| nodes | string | no | List of cluster node names with optional priority. | +| strict | boolean | no | Describes whether the node affinity rule is strict or non-strict. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/ha/rules/{rule} + +Delete HA rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| rule | string | yes | HA rule identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/rules/{rule} + +Read HA rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| rule | string | yes | HA rule identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/ha/rules/{rule} + +Update HA rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| rule | string | yes | HA rule identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | HA rule type. | +| affinity | string | no | 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'). | +| comment | string | no | HA rule description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Whether the HA rule is disabled. | +| nodes | string | no | List of cluster node names with optional priority. | +| resources | string | no | 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). | +| strict | boolean | no | Describes whether the node affinity rule is strict or non-strict. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ha/status + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/ha/status/arm-ha + +Request re-arming the HA stack after it was disarmed. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ha/status/current + +Get HA manager status. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/ha/status/disarm-ha + +Request disarming the HA stack, releasing all watchdogs cluster-wide. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| resource-mode | string | yes | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/ha/status/manager_status + +Get full HA manager status, including LRM status. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/jobs + +Index for jobs related endpoints. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Directory index.", + "items": { + "properties": { + "subdir": { + "description": "API sub-directory endpoint", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/jobs/realm-sync + +List configured realm-sync-jobs. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/jobs/realm-sync/{id} + +Delete realm-sync job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/jobs/realm-sync/{id} + +Read realm-sync job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/jobs/realm-sync/{id} + +Create new realm-sync job. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the job. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| schedule | string | yes | Backup schedule. The format is a subset of `systemd` calendar events. | +| comment | string | no | Description for the Job. | +| enable-new | boolean | no | Enable newly synced users immediately. | +| enabled | boolean | no | Determines if the job is enabled. | +| realm | string | no | Authentication domain ID | +| remove-vanished | string | no | 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). | +| scope | string | no | Select what to sync. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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/'." +} +``` + +## Raw schema + +```json +{ + "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 /cluster/jobs/realm-sync/{id} + +Update realm-sync job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the job. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| schedule | string | yes | Backup schedule. The format is a subset of `systemd` calendar events. | +| comment | string | no | Description for the Job. | +| delete | string | no | A list of settings you want to delete. | +| enable-new | boolean | no | Enable newly synced users immediately. | +| enabled | boolean | no | Determines if the job is enabled. | +| remove-vanished | string | no | 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). | +| scope | string | no | Select what to sync. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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/'." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/jobs/schedule-analyze + +Returns a list of future schedule runtimes. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| schedule | string | yes | Job schedule. The format is a subset of `systemd` calendar events. | +| iterations | integer | no | Number of event-iteration to simulate and return. | +| starttime | integer | no | UNIX timestamp to start the calculation from. Defaults to the current time. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/log + +Read cluster log + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max | integer | no | Maximum number of entries. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Syslog' on '/' in order to get all logs.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/mapping + +List resource types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/mapping/dir + +List directory mapping + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| check-node | string | no | If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/dir + +Create a new directory mapping. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the directory mapping | +| map | array | yes | A list of maps for the cluster nodes. | +| description | string | no | Description of the directory mapping | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/mapping/dir/{id} + +Remove directory mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/dir/{id} + +Get directory mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/dir/{id} + +Update a directory mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the directory mapping | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description of the directory mapping | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| map | array | no | A list of maps for the cluster nodes. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/mapping/pci + +List PCI Hardware Mapping + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| check-node | string | no | If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/pci + +Create a new hardware mapping. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical PCI mapping. | +| map | array | yes | A list of maps for the cluster nodes. | +| description | string | no | Description of the logical PCI device. | +| live-migration-capable | boolean | no | Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work. | +| mdev | boolean | no | Marks the device(s) as being capable of providing mediated devices. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/mapping/pci/{id} + +Remove Hardware Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/pci/{id} + +Get PCI Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/pci/{id} + +Update a hardware mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical PCI mapping. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description of the logical PCI device. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| live-migration-capable | boolean | no | Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work. | +| map | array | no | A list of maps for the cluster nodes. | +| mdev | boolean | no | Marks the device(s) as being capable of providing mediated devices. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/mapping/usb + +List USB Hardware Mappings + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| check-node | string | no | If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/usb + +Create a new hardware mapping. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical USB mapping. | +| map | array | yes | A list of maps for the cluster nodes. | +| description | string | no | Description of the logical USB device. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/mapping/usb/{id} + +Remove Hardware Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/usb/{id} + +Get USB Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/mapping/usb/{id} + +Update a hardware mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical USB mapping. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| map | array | yes | A list of maps for the cluster nodes. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description of the logical USB device. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/metrics + +Metrics index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/metrics/export + +Retrieve metrics of the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| history | boolean | no | Also return historic values. Returns full available metric history unless `start-time` is also set | +| local-only | boolean | no | Only return metrics for the current node instead of the whole cluster | +| node-list | string | no | Only return metrics from nodes passed as comma-separated list | +| start-time | integer | no | Only include metrics with a timestamp > start-time. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/metrics/server + +List configured metric servers. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/metrics/server/{id} + +Remove Metric server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/metrics/server/{id} + +Read metric server configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/metrics/server/{id} + +Create a new external metric server config + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the entry. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | server network port | +| server | string | yes | server dns name or IP address | +| type | string | yes | Plugin type. | +| api-path-prefix | string | no | An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy. | +| bucket | string | no | The InfluxDB bucket/db. Only necessary when using the http v2 api. | +| disable | boolean | no | Flag to disable the plugin. | +| influxdbproto | string | no | | +| max-body-size | integer | no | InfluxDB max-body-size in bytes. Requests are batched up to this size. | +| mtu | integer | no | MTU for metrics transmission over UDP | +| organization | string | no | The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api. | +| otel-compression | string | no | Compression algorithm for requests | +| otel-headers | string | no | Custom HTTP headers (JSON format, base64 encoded) | +| otel-max-body-size | integer | no | Maximum request body size in bytes | +| otel-path | string | no | OTLP endpoint path | +| otel-protocol | string | no | HTTP protocol | +| otel-resource-attributes | string | no | Additional resource attributes as JSON, base64 encoded | +| otel-timeout | integer | no | HTTP request timeout in seconds | +| otel-verify-ssl | boolean | no | Verify SSL certificates | +| path | string | no | root graphite path (ex: proxmox.mycluster.mykey) | +| proto | string | no | Protocol to send graphite data. TCP or UDP (default) | +| timeout | integer | no | graphite TCP socket timeout (default=1) | +| token | string | no | The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead. | +| verify-certificate | boolean | no | Set to 0 to disable certificate verification for https endpoints. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/metrics/server/{id} + +Update metric server configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the entry. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | server network port | +| server | string | yes | server dns name or IP address | +| api-path-prefix | string | no | An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy. | +| bucket | string | no | The InfluxDB bucket/db. Only necessary when using the http v2 api. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable the plugin. | +| influxdbproto | string | no | | +| max-body-size | integer | no | InfluxDB max-body-size in bytes. Requests are batched up to this size. | +| mtu | integer | no | MTU for metrics transmission over UDP | +| organization | string | no | The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api. | +| otel-compression | string | no | Compression algorithm for requests | +| otel-headers | string | no | Custom HTTP headers (JSON format, base64 encoded) | +| otel-max-body-size | integer | no | Maximum request body size in bytes | +| otel-path | string | no | OTLP endpoint path | +| otel-protocol | string | no | HTTP protocol | +| otel-resource-attributes | string | no | Additional resource attributes as JSON, base64 encoded | +| otel-timeout | integer | no | HTTP request timeout in seconds | +| otel-verify-ssl | boolean | no | Verify SSL certificates | +| path | string | no | root graphite path (ex: proxmox.mycluster.mykey) | +| proto | string | no | Protocol to send graphite data. TCP or UDP (default) | +| timeout | integer | no | graphite TCP socket timeout (default=1) | +| token | string | no | The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead. | +| verify-certificate | boolean | no | Set to 0 to disable certificate verification for https endpoints. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/nextid + +Get next free VMID. Pass a VMID to assert that its free (at time of check). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "description": "The next free VMID.", + "type": "integer" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications + +Index for notification-related API endpoints. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/endpoints + +Index for all available endpoint types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/endpoints/gotify + +Returns a list of all gotify endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/gotify + +Create a new gotify endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | +| server | string | yes | Server URL | +| token | string | yes | Secret token | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/notifications/endpoints/gotify/{name} + +Remove gotify endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/gotify/{name} + +Return a specific gotify endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the endpoint. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/gotify/{name} + +Update existing gotify endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| server | string | no | Server URL | +| token | string | no | Secret token | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/endpoints/sendmail + +Returns a list of all sendmail endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/sendmail + +Create a new sendmail endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | +| author | string | no | Author of the mail | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | +| from-address | string | no | `From` address for the mail | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/notifications/endpoints/sendmail/{name} + +Remove sendmail endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/sendmail/{name} + +Return a specific sendmail endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/sendmail/{name} + +Update existing sendmail endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| author | string | no | Author of the mail | +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| from-address | string | no | `From` address for the mail | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/endpoints/smtp + +Returns a list of all smtp endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/smtp + +Create a new smtp endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| from-address | string | yes | `From` address for the mail | +| name | string | yes | The name of the endpoint. | +| server | string | yes | The address of the SMTP server. | +| author | string | no | Author of the mail. Defaults to 'Proxmox VE'. | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | +| mode | string | no | Determine which encryption method shall be used for the connection. | +| password | string | no | Password for SMTP authentication | +| port | integer | no | 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. | +| username | string | no | Username for SMTP authentication | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/notifications/endpoints/smtp/{name} + +Remove smtp endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/smtp/{name} + +Return a specific smtp endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/smtp/{name} + +Update existing smtp endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| author | string | no | Author of the mail. Defaults to 'Proxmox VE'. | +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| from-address | string | no | `From` address for the mail | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | +| mode | string | no | Determine which encryption method shall be used for the connection. | +| password | string | no | Password for SMTP authentication | +| port | integer | no | 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. | +| server | string | no | The address of the SMTP server. | +| username | string | no | Username for SMTP authentication | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/endpoints/webhook + +Returns a list of all webhook endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/webhook + +Create a new webhook endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| method | string | yes | HTTP method | +| name | string | yes | The name of the endpoint. | +| url | string | yes | Server URL | +| body | string | no | HTTP body, base64 encoded | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | +| header | array | no | HTTP headers to set. These have to be formatted as a property string in the format name=,value= | +| secret | array | no | Secrets to set. These have to be formatted as a property string in the format name=,value= | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/notifications/endpoints/webhook/{name} + +Remove webhook endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/webhook/{name} + +Return a specific webhook endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the endpoint. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/endpoints/webhook/{name} + +Update existing webhook endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| body | string | no | HTTP body, base64 encoded | +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| header | array | no | HTTP headers to set. These have to be formatted as a property string in the format name=,value= | +| method | string | no | HTTP method | +| secret | array | no | Secrets to set. These have to be formatted as a property string in the format name=,value= | +| url | string | no | Server URL | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/matcher-field-values + +Returns known notification metadata fields and their known values + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/matcher-fields + +Returns known notification metadata fields + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "name": { + "description": "Name of the field.", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/matchers + +Returns a list of all matchers + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/matchers + +Create a new matcher + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the matcher. | +| comment | string | no | Comment | +| disable | boolean | no | Disable this matcher | +| invert-match | boolean | no | Invert match of the whole matcher | +| match-calendar | array | no | Match notification timestamp | +| match-field | array | no | Metadata fields to match (regex or exact match). Must be in the form (regex\|exact):= | +| match-severity | array | no | Notification severities to match | +| mode | string | no | Choose between 'all' and 'any' for when multiple properties are specified | +| target | array | no | Targets to notify on match | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/notifications/matchers/{name} + +Remove matcher + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/matchers/{name} + +Return a specific matcher + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/notifications/matchers/{name} + +Update existing matcher + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the matcher. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this matcher | +| invert-match | boolean | no | Invert match of the whole matcher | +| match-calendar | array | no | Match notification timestamp | +| match-field | array | no | Metadata fields to match (regex or exact match). Must be in the form (regex\|exact):= | +| match-severity | array | no | Notification severities to match | +| mode | string | no | Choose between 'all' and 'any' for when multiple properties are specified | +| target | array | no | Targets to notify on match | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/notifications/targets + +Returns a list of all entities that can be used as notification targets. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/notifications/targets/{name}/test + +Send a test notification to a provided target. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the target. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/options + +Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/options + +Set datacenter options. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| bwlimit | string | no | Set I/O bandwidth limit for various operations (in KiB/s). | +| consent-text | string | no | Consent text that is displayed before logging in. | +| console | string | no | 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. | +| crs | string | no | Cluster resource scheduling settings. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file. | +| email_from | string | no | Specify email address to send notification from (default is root@$hostname) | +| fencing | string | no | 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. WARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP | +| ha | string | no | Cluster wide HA settings. | +| http_proxy | string | no | Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/') | +| keyboard | string | no | Default keybord layout for vnc server. | +| language | string | no | Default GUI language. | +| location | string | no | The location of the cluster. | +| mac_prefix | string | no | 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). | +| max_workers | integer | no | Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager. | +| migration | string | no | For cluster wide migration settings. | +| migration_unsecure | boolean | no | 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! | +| next-id | string | no | Control the range for the free VMID auto-selection pool. | +| notify | string | no | Cluster-wide notification settings. | +| registered-tags | string | no | 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`. | +| replication | string | no | For cluster wide replication settings. | +| tag-style | string | no | Tag style options. | +| u2f | string | no | u2f | +| user-tag-access | string | no | Privilege options for user-settable tags | +| webauthn | string | no | webauthn configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/qemu + +Cluster-wide QEMU index + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/qemu/cpu-flags + +List of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| accel | string | no | Acceleration type to check node compatibility for. | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/nodes", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/mapping/cpu", + [ + "Mapping.Audit", + "Mapping.Use", + "Mapping.Modify" + ], + "any", + 1 + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/qemu/custom-cpu-models + +List all custom CPU model definitions visible to the user. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where the user has 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/cpu/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/qemu/custom-cpu-models + +Add a custom CPU model definition. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | Name for the custom CPU model. The 'custom-' prefix is optional. | +| reported-model | string | yes | 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. | +| flags | string | no | 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 | +| guest-phys-bits | integer | no | Number of physical address bits available to the guest. | +| hidden | boolean | no | Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture. | +| hv-vendor-id | string | no | The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID. | +| level | integer | no | 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. | +| phys-bits | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/cpu", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/qemu/custom-cpu-models/{cputype} + +Delete a custom CPU model definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | The custom model to delete. The 'custom-' prefix is optional. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/qemu/custom-cpu-models/{cputype} + +Retrieve details about a specific custom CPU model. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | Name of the CPU model to query. The 'custom-' prefix is optional. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/qemu/custom-cpu-models/{cputype} + +Update a custom CPU model definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | Name for the custom CPU model. The 'custom-' prefix is optional. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of properties to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| flags | string | no | 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 | +| guest-phys-bits | integer | no | Number of physical address bits available to the guest. | +| hidden | boolean | no | Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture. | +| hv-vendor-id | string | no | The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID. | +| level | integer | no | 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. | +| phys-bits | string | no | 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. | +| reported-model | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/replication + +List replication jobs. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/replication + +Create a new replication job + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| target | string | yes | Target node. | +| type | string | yes | Section type. | +| comment | string | no | Description. | +| disable | boolean | no | Flag to disable/deactivate the entry. | +| rate | number | no | Rate limit in mbps (megabytes per second) as floating point number. | +| remove_job | string | no | 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. | +| schedule | string | no | Storage replication schedule. The format is a subset of `systemd` calendar events. | +| source | string | no | For internal use, to detect if the guest was stolen. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/replication/{id} + +Mark replication job for removal. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Will remove the jobconfig entry, but will not cleanup. | +| keep | boolean | no | Keep replicated data at target (do not remove). | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/replication/{id} + +Read replication job configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/replication/{id} + +Update replication job configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable/deactivate the entry. | +| rate | number | no | Rate limit in mbps (megabytes per second) as floating point number. | +| remove_job | string | no | 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. | +| schedule | string | no | Storage replication schedule. The format is a subset of `systemd` calendar events. | +| source | string | no | For internal use, to detect if the guest was stolen. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/resources + +Resources index (cluster wide). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Resource type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn + +Apply sdn controller changes && reload. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | +| release-lock | boolean | no | When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/controllers + +SDN controllers index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | +| type | string | no | Only list sdn controllers of specific type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/controllers + +Create a new sdn controller object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | +| type | string | yes | Plugin type. | +| asn | integer | no | autonomous system number | +| bgp-mode | string | no | Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. | +| bgp-multipath-as-path-relax | boolean | no | Consider different AS paths of equal length for multipath computation. | +| ebgp | boolean | no | Enable eBGP (remote-as external). | +| ebgp-multihop | integer | no | Set maximum amount of hops for eBGP peers. | +| fabric | string | no | SDN fabric to use as underlay for this EVPN controller. | +| isis-domain | string | no | Name of the IS-IS domain. | +| isis-ifaces | string | no | Comma-separated list of interfaces where IS-IS should be active. | +| isis-net | string | no | Network Entity title for this node in the IS-IS network. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| loopback | string | no | Name of the loopback/dummy interface that provides the Router-IP. | +| node | string | no | The cluster node name. | +| nodes | string | no | List of cluster node names. | +| peer-group-name | string | no | Name of the peer group for this EVPN controller | +| peers | string | no | peers address list. | +| route-map-in | string | no | Route Map that should be applied for incoming routes | +| route-map-out | string | no | Route Map that should be applied for outgoing routes | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/controllers/{controller} + +Delete sdn controller object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/controllers/{controller} + +Read sdn controller configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers/{controller}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/controllers/{controller} + +Update sdn controller object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| asn | integer | no | autonomous system number | +| bgp-mode | string | no | Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. | +| bgp-multipath-as-path-relax | boolean | no | Consider different AS paths of equal length for multipath computation. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| ebgp | boolean | no | Enable eBGP (remote-as external). | +| ebgp-multihop | integer | no | Set maximum amount of hops for eBGP peers. | +| fabric | string | no | SDN fabric to use as underlay for this EVPN controller. | +| isis-domain | string | no | Name of the IS-IS domain. | +| isis-ifaces | string | no | Comma-separated list of interfaces where IS-IS should be active. | +| isis-net | string | no | Network Entity title for this node in the IS-IS network. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| loopback | string | no | Name of the loopback/dummy interface that provides the Router-IP. | +| node | string | no | The cluster node name. | +| nodes | string | no | List of cluster node names. | +| peer-group-name | string | no | Name of the peer group for this EVPN controller | +| peers | string | no | peers address list. | +| route-map-in | string | no | Route Map that should be applied for incoming routes | +| route-map-out | string | no | Route Map that should be applied for outgoing routes | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/dns + +SDN dns index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list sdn dns of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "dns": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{dns}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/dns + +Create a new sdn dns object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | +| key | string | yes | | +| type | string | yes | Plugin type. | +| url | string | yes | | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| reversemaskv6 | integer | no | | +| reversev6mask | integer | no | | +| ttl | integer | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/dns/{dns} + +Delete sdn dns object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/dns/{dns} + +Read sdn dns configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns/{dns}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/dns/{dns} + +Update sdn dns object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| key | string | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| reversemaskv6 | integer | no | | +| ttl | integer | no | | +| url | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/dry-run + +Dry-run the SDN apply action and return the difference between the current configuration and the pending configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/fabrics + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/fabrics/all + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + }, + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/fabrics/fabric + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/fabrics/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/fabrics/fabric + +Add a fabric + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| redistribute | array | yes | | +| area | string | no | OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust. | +| csnp_interval | number | no | The csnp_interval property for Openfabric | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| hello_interval | number | no | The hello_interval property for Openfabric | +| ip_prefix | string | no | The IP prefix for Node IPs | +| ip6_prefix | string | no | The IP prefix for Node IPs | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| persistent_keepalive | number | no | 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 | +| route_filter | string | no | A prefix list that should be used for filtering routes that are to be installed into the kernel routing table | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/fabrics/fabric/{id} + +Add a fabric + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/fabrics/fabric/{id} + +Update a fabric + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/fabrics/fabric/{id} + +Update a fabric + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | array | yes | | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| redistribute | array | yes | | +| area | string | no | OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust. | +| csnp_interval | number | no | The csnp_interval property for Openfabric | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| hello_interval | number | no | The hello_interval property for Openfabric | +| ip_prefix | string | no | The IP prefix for Node IPs | +| ip6_prefix | string | no | The IP prefix for Node IPs | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| persistent_keepalive | number | no | 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 | +| route_filter | string | no | A prefix list that should be used for filtering routes that are to be installed into the kernel routing table | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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": [ + "hello_interval", + "csnp_interval", + "route_filter" + ], + "type": "string" + }, + "optional": 1, + "type": "array" + }, + { + "instance-types": [ + "bgp" + ], + "items": { + "enum": [ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/fabrics/node + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + }, + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/fabrics/node/{fabric_id} + +SDN Fabrics Index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + }, + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit" + ] + ], + "description": "Only returns nodes where you have 'Sys.Audit' or 'Sys.Modify' permissions." +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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 /cluster/sdn/fabrics/node/{fabric_id} + +Add a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| interfaces | array | yes | | +| node_id | string | yes | Identifier for nodes in an SDN fabric | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| allowed_ips | array | no | A list of IPs that are routable via this node in the WireGuard fabric. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| endpoint | string | no | The endpoint used for connecting to this node. | +| ip | string | no | IPv4 address for this node | +| ip6 | string | no | IPv6 address for this node | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| peers | array | no | | +| public_key | string | no | The public key for the external node. | +| role | string | no | The role of this node in the WireGuard fabric. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/fabrics/node/{fabric_id}/{node_id} + +Add a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | +| node_id | string | yes | Identifier for nodes in an SDN fabric | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/fabrics/node/{fabric_id}/{node_id} + +Get a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | +| node_id | string | yes | Identifier for nodes in an SDN fabric | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" + } + }, + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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 /cluster/sdn/fabrics/node/{fabric_id}/{node_id} + +Update a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | +| node_id | string | yes | Identifier for nodes in an SDN fabric | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | array | yes | | +| interfaces | array | yes | | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| allowed_ips | array | no | A list of IPs that are routable via this node in the WireGuard fabric. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| endpoint | string | no | The endpoint used for connecting to this node. | +| ip | string | no | IPv4 address for this node | +| ip6 | string | no | IPv6 address for this node | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| peers | array | no | | +| public_key | string | no | The public key for the external node. | +| role | string | no | The role of this node in the WireGuard fabric. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/ipams + +SDN ipams index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list sdn ipams of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "ipam": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{ipam}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/ipams + +Create a new sdn ipam object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | +| type | string | yes | Plugin type. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| section | integer | no | | +| token | string | no | | +| url | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/ipams/{ipam} + +Delete sdn ipam object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/ipams/{ipam} + +Read sdn ipam configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams/{ipam}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/ipams/{ipam} + +Update sdn ipam object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| section | integer | no | | +| token | string | no | | +| url | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/ipams/{ipam}/status + +List PVE IPAM Entries + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/lock + +Release global lock for SDN configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | if true, allow releasing lock without providing the token | +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/lock + +Acquire global lock for SDN configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| allow-pending | boolean | no | if true, allow acquiring lock even though there are pending changes | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/prefix-lists + +List Prefix Lists + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | +| verbose | boolean | no | If 0, only returns id - otherwise returns all properties. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only returns prefix list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/prefix-lists + +Create Prefix List + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| entries | array | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/prefix-lists/{id} + +Delete Prefix List + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/prefix-lists/{id} + +Get Prefix List + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/prefix-lists/{id} + +Update Prefix List + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | array | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| entries | array | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/prefix-lists/{id}/entries + +List Prefix List Entries + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{seq}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/prefix-lists/{id}/entries + +Create Prefix List Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | | +| prefix | string | yes | | +| ge | integer | no | | +| le | integer | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| seq | integer | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/prefix-lists/{id}/entries/{url_seq} + +Delete Prefix List Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/prefix-lists/{id}/entries/{url_seq} + +Get Prefix List Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/prefix-lists/{id}/entries/{url_seq} + +Update Prefix List Entry + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | | +| delete | array | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| ge | integer | no | | +| le | integer | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| prefix | string | no | | +| seq | integer | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /cluster/sdn/rollback + +Rollback pending changes to SDN configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | +| release-lock | boolean | no | When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/route-maps + +List Route Maps + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only returns route maps where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/route-maps/entries + +Lists all route map entries. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only returns route map entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/route-maps/entries + +Create Route Map entry + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Matching policy of a route map entry. | +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | +| call | string | no | The SDN route map identifier | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| exit-action | string | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| match | array | no | | +| set | array | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/route-maps/entries/{route-map-id} + +List all entries for a given Route Map + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order} + +Delete Route Map Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order} + +Get Route Map Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order} + +Update Route Map Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Matching policy of a route map entry. | +| call | string | no | The SDN route map identifier | +| delete | array | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| exit-action | string | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| match | array | no | | +| set | array | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/vnets + +SDN vnets index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets + +Create a new sdn vnet object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| zone | string | yes | Name of the zone this VNet belongs to. | +| alias | string | no | Alias name of the VNet. | +| isolate-ports | boolean | no | If true, sets the isolated property for all interfaces on the bridge of this VNet. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| tag | integer | no | VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones). | +| type | string | no | Type of the VNet. | +| vlanaware | boolean | no | Allow VLANs to pass through this vnet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/vnets/{vnet} + +Delete sdn vnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet} + +Read sdn vnet configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet} + +Update sdn vnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| alias | string | no | Alias name of the VNet. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| isolate-ports | boolean | no | If true, sets the isolated property for all interfaces on the bridge of this VNet. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| tag | integer | no | VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones). | +| vlanaware | boolean | no | Allow VLANs to pass through this vnet. | +| zone | string | no | Name of the zone this VNet belongs to. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/vnets/{vnet}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/vnets/{vnet}/firewall/options + +Get vnet firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable/disable firewall rules. | +| log_level_forward | string | no | Log level for forwarded traffic. | +| policy_forward | string | no | Forward policy. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/vnets/{vnet}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/vnets/{vnet}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/vnets/{vnet}/ips + +Delete IP Mappings in a VNet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ip | string | yes | The IP address to delete | +| zone | string | yes | The SDN zone object identifier. | +| mac | string | no | Unicast MAC address. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/ips + +Create IP Mapping in a VNet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ip | string | yes | The IP address to associate with the given MAC address | +| zone | string | yes | The SDN zone object identifier. | +| mac | string | no | Unicast MAC address. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/ips + +Update IP Mapping in a VNet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ip | string | yes | The IP address to associate with the given MAC address | +| zone | string | yes | The SDN zone object identifier. | +| mac | string | no | Unicast MAC address. | +| vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/vnets/{vnet}/subnets + +SDN subnets index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{subnet}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/subnets + +Create a new sdn subnet object. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | associated vnet | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| type | string | yes | | +| dhcp-dns-server | string | no | IP address for the DNS server | +| dhcp-range | array | no | A list of DHCP ranges for this subnet | +| dnszoneprefix | string | no | dns domain zone prefix ex: 'adm' -> .adm.mydomain.com | +| gateway | string | no | Subnet Gateway: Will be assign on vnet for layer3 zones | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| snat | boolean | no | enable masquerade for this subnet if pve-firewall | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/vnets/{vnet}/subnets/{subnet} + +Delete sdn subnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/subnets/{subnet} + +Read sdn subnet configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/vnets/{vnet}/subnets/{subnet} + +Update sdn subnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| vnet | string | no | associated vnet | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| dhcp-dns-server | string | no | IP address for the DNS server | +| dhcp-range | array | no | A list of DHCP ranges for this subnet | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dnszoneprefix | string | no | dns domain zone prefix ex: 'adm' -> .adm.mydomain.com | +| gateway | string | no | Subnet Gateway: Will be assign on vnet for layer3 zones | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| snat | boolean | no | enable masquerade for this subnet if pve-firewall | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/sdn/zones + +SDN zones index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | +| type | string | no | Only list SDN zones of specific type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/zones + +Create a new sdn zone object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | Plugin type. | +| zone | string | yes | The SDN zone object identifier. | +| advertise-subnets | boolean | no | Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). | +| bridge | string | no | The bridge for which VLANs should be managed. | +| bridge-disable-mac-learning | boolean | no | Disable auto mac learning. | +| controller | string | no | Controller for this zone. | +| dhcp | string | no | Type of the DHCP backend for this zone | +| disable-arp-nd-suppression | boolean | no | Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. | +| dns | string | no | dns api server | +| dnszone | string | no | dns domain zone ex: mydomain.com | +| dp-id | integer | no | Faucet dataplane id | +| exitnodes | string | no | List of cluster node names. | +| exitnodes-local-routing | boolean | no | Allow exitnodes to connect to EVPN guests. | +| exitnodes-primary | string | no | Force traffic through this exitnode first. | +| fabric | string | no | SDN fabric to use as underlay for this VXLAN zone. | +| ipam | string | no | use a specific ipam | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| mac | string | no | Anycast logical router mac address. | +| mtu | integer | no | MTU of the zone, will be used for the created VNet bridges. | +| nodes | string | no | List of cluster node names. | +| peers | string | no | Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. | +| reversedns | string | no | reverse dns api server | +| rt-import | string | no | List of Route Targets that should be imported into the VRF of the zone. | +| secondary-controllers | array | no | Additional controllers. | +| tag | integer | no | Service-VLAN Tag (outer VLAN) | +| vlan-protocol | string | no | Which VLAN protocol should be used for the creation of the QinQ zone. | +| vrf-vxlan | integer | no | VNI for the zone VRF. | +| vxlan-port | integer | no | UDP port that should be used for the VXLAN tunnel (default 4789). | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /cluster/sdn/zones/{zone} + +Delete sdn zone object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/zones/{zone} + +Read sdn zone configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /cluster/sdn/zones/{zone} + +Update sdn zone object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| advertise-subnets | boolean | no | Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). | +| bridge | string | no | The bridge for which VLANs should be managed. | +| bridge-disable-mac-learning | boolean | no | Disable auto mac learning. | +| controller | string | no | Controller for this zone. | +| delete | string | no | A list of settings you want to delete. | +| dhcp | string | no | Type of the DHCP backend for this zone | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable-arp-nd-suppression | boolean | no | Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. | +| dns | string | no | dns api server | +| dnszone | string | no | dns domain zone ex: mydomain.com | +| dp-id | integer | no | Faucet dataplane id | +| exitnodes | string | no | List of cluster node names. | +| exitnodes-local-routing | boolean | no | Allow exitnodes to connect to EVPN guests. | +| exitnodes-primary | string | no | Force traffic through this exitnode first. | +| fabric | string | no | SDN fabric to use as underlay for this VXLAN zone. | +| ipam | string | no | use a specific ipam | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| mac | string | no | Anycast logical router mac address. | +| mtu | integer | no | MTU of the zone, will be used for the created VNet bridges. | +| nodes | string | no | List of cluster node names. | +| peers | string | no | Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. | +| reversedns | string | no | reverse dns api server | +| rt-import | string | no | List of Route Targets that should be imported into the VRF of the zone. | +| secondary-controllers | array | no | Additional controllers. | +| tag | integer | no | Service-VLAN Tag (outer VLAN) | +| vlan-protocol | string | no | Which VLAN protocol should be used for the creation of the QinQ zone. | +| vrf-vxlan | integer | no | VNI for the zone VRF. | +| vxlan-port | integer | no | UDP port that should be used for the VXLAN tunnel (default 4789). | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/status + +Get cluster status information. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /cluster/tasks + +List recent tasks (cluster wide). + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "upid": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes + +Cluster node index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node} + +Node index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/aplinfo + +Get list of appliances. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/aplinfo + +Download appliance templates. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage where the template will be stored | +| template | string | yes | The template which will downloaded | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/apt + +Directory index for apt (Advanced Package Tool). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/apt/changelog + +Get package changelogs. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Package name. | +| version | string | no | Package version. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/apt/repositories + +Get APT repository information. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/apt/repositories + +Change the properties of a repository. Currently only allows enabling/disabling. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| index | integer | yes | Index within the file (starting from 0). | +| path | string | yes | Path to the containing file. | +| digest | string | no | Digest to detect modifications. | +| enabled | boolean | no | Whether the repository should be enabled or not. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/apt/repositories + +Add a standard repository to the configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| handle | string | yes | Handle that identifies a repository. | +| digest | string | no | Digest to detect modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/apt/update + +List available updates. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/apt/update + +This is used to resynchronize the package index files from their sources (apt-get update). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| notify | boolean | no | Send notification about new packages. | +| quiet | boolean | no | Only produces output suitable for logging, omitting progress indicators. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/apt/versions + +Get package information for important Proxmox packages. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/capabilities + +Node capabilities index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/capabilities/qemu + +QEMU capabilities index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/capabilities/qemu/cpu + +List all custom and default CPU models. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/capabilities/qemu/cpu-flags + +List of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| accel | string | no | Acceleration type to check node compatibility for. | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/capabilities/qemu/machines + +Get available QEMU/KVM machine types. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/capabilities/qemu/migration + +Get node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/cfg + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/cfg/db + +Get the Ceph configuration database. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/cfg/raw + +Get the Ceph configuration file. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/cfg/value + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| config-keys | string | yes | List of
: items separated by semicolon, comma or space. | + +## Returns + +```json +{ + "description": "Two-level map of {section} -> {key} -> value. Underscores in section and key names are normalised to hyphens.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/cmd-safety + +Heuristical check if it is safe to perform an action. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Action to check | +| id | string | yes | ID of the service | +| service | string | yes | Service type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/crush + +Get OSD crush map + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/fs + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/ceph/fs/{name} + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The Ceph filesystem name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| remove-pools | boolean | no | Remove the metadata and data pools used by this filesystem. | +| remove-storages | boolean | no | Remove pveceph-managed storages configured for this filesystem. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/fs/{name} + +Create a Ceph filesystem + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| name | string | no | The ceph filesystem name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| add-storage | boolean | no | Configure the created CephFS as storage for this cluster. | +| pg_num | integer | no | Number of placement groups for the backing data pool. The metadata pool will use a quarter of this. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/ceph/init + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cluster-network | string | no | Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it | +| disable_cephx | boolean | no | Disable cephx authentication. WARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private! | +| min_size | integer | no | Minimum number of available replicas per object to allow I/O | +| network | string | no | Use specific network for all ceph related traffic | +| pg_bits | integer | no | Placement group bits, used to specify the default number of placement groups. Depreacted. This setting was deprecated in recent Ceph versions. | +| size | integer | no | Targeted number of replicas per object | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/log + +Read ceph log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted. | +| start | integer | no | Offset of the first log line to return (0-based). | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Log-file line number (1-based).", + "type": "integer" + }, + "t": { + "description": "Log line text.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/mds + +MDS directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/ceph/mds/{name} + +Destroy Ceph Metadata Server + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name (ID) of the mds | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/mds/{name} + +Create Ceph Metadata Server (MDS) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| name | string | no | The ID for the mds, when omitted the same as the nodename | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| hotstandby | boolean | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/mgr + +MGR directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/ceph/mgr/{id} + +Destroy Ceph Manager. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the manager | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/mgr/{id} + +Create Ceph Manager + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| id | string | no | The ID for the manager, when omitted the same as the nodename. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/mon + +Get Ceph monitor list. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/ceph/mon/{monid} + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| monid | string | yes | Monitor ID | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/mon/{monid} + +Create a Ceph Monitor. Also auto-creates a Manager for the first monitor. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| monid | string | no | The ID for the monitor, when omitted the same as the nodename. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| mon-address | string | no | Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/osd + +Get Ceph osd list/tree. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/osd + +Create OSD + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dev | string | yes | Block device name. | +| crush-device-class | string | no | Set the device class of the OSD in crush. | +| db_dev | string | no | Block device name for block.db. | +| db_dev_size | number | no | Size in GiB for block.db. | +| encrypted | boolean | no | Enables encryption of the OSD. | +| osds-per-device | integer | no | OSD services per physical device. Only useful for fast NVMe devices to utilize their performance better. Mutually exclusive with 'db_dev' and 'wal_dev'. | +| wal_dev | string | no | Block device name for block.wal. | +| wal_dev_size | number | no | Size in GiB for block.wal. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/ceph/osd/{osdid} + +Destroy OSD + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup | boolean | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/osd/{osdid} + +OSD index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/ceph/osd/{osdid}/in + +ceph osd in + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/osd/{osdid}/lv-info + +Get OSD volume details + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | OSD device type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/osd/{osdid}/metadata + +Get OSD details + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/ceph/osd/{osdid}/out + +ceph osd out + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/ceph/osd/{osdid}/scrub + +Instruct the OSD to scrub. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| deep | boolean | no | If set, instructs a deep scrub instead of a normal one. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/pool + +List all pools and their settings (which are settable by the POST/PUT endpoints). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/pool + +Create Ceph pool + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| add_storages | boolean | no | 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). | +| application | string | no | The application of the pool. | +| crush_rule | string | no | The rule to use for mapping object placement in the cluster. | +| erasure-coding | string | no | 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. | +| min_size | integer | no | Minimum number of replicas per object | +| pg_autoscale_mode | string | no | The automatic PG scaling mode of the pool. | +| pg_num | integer | no | Number of placement groups. | +| pg_num_min | integer | no | Minimal number of placement groups. | +| size | integer | no | Number of replicas per object | +| target_size | string | no | The estimated target size of the pool for the PG autoscaler. | +| target_size_ratio | number | no | The estimated target ratio of the pool for the PG autoscaler. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/ceph/pool/{name} + +Destroy pool + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | If true, destroys pool even if in use | +| remove_ecprofile | boolean | no | Remove the erasure code profile. Defaults to true, if applicable. | +| remove_storages | boolean | no | Remove all pveceph-managed storages configured for this pool | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/pool/{name} + +Pool index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/ceph/pool/{name} + +Change POOL settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| application | string | no | The application of the pool. | +| crush_rule | string | no | The rule to use for mapping object placement in the cluster. | +| min_size | integer | no | Minimum number of replicas per object | +| pg_autoscale_mode | string | no | The automatic PG scaling mode of the pool. | +| pg_num | integer | no | Number of placement groups. | +| pg_num_min | integer | no | Minimal number of placement groups. | +| size | integer | no | Number of replicas per object | +| target_size | string | no | The estimated target size of the pool for the PG autoscaler. | +| target_size_ratio | number | no | The estimated target ratio of the pool for the PG autoscaler. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/pool/{name}/status + +Show the current pool status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| verbose | boolean | no | If enabled, will display additional data(eg. statistics). | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/ceph/restart + +Restart ceph services. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| service | string | no | Ceph service name. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/rules + +List ceph rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "name": { + "description": "Name of the CRUSH rule.", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/ceph/start + +Start ceph services. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| service | string | no | Ceph service name. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/ceph/status + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/ceph/stop + +Stop ceph services. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| service | string | no | Ceph service name. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/certificates + +Node index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/certificates/acme + +ACME index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/certificates/acme/certificate + +Revoke existing certificate from CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/certificates/acme/certificate + +Order a new certificate from ACME-compatible CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Overwrite existing custom certificate. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/certificates/acme/certificate + +Renew existing certificate from CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Force renewal even if expiry is more than 30 days away. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/certificates/custom + +DELETE custom certificate chain and key. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| restart | boolean | no | Restart pveproxy. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/certificates/custom + +Upload or update custom certificate chain and key. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| certificates | string | yes | PEM encoded certificate (chain). | +| force | boolean | no | Overwrite existing custom or ACME certificate files. | +| key | string | no | PEM encoded private key. | +| restart | boolean | no | Restart pveproxy. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/certificates/info + +Get information about node's certificates. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/config + +Get node configuration options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| property | string | no | Return only a specific property from the node configuration. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/config + +Set node configuration options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acme | string | no | Node specific ACME settings. | +| acmedomain[n] | string | no | ACME domain and validation plugin | +| ballooning-target | integer | no | RAM usage target for ballooning (in percent of total memory) | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| location | string | no | The location of the node. Overrides the default from the datacenter config. | +| startall-onboot-delay | integer | no | Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled. | +| wakeonlan | string | no | Node specific wake on LAN settings. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/disks + +Node index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/disks/directory + +PVE Managed Directory storages. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/disks/directory + +Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| device | string | yes | The block device you want to create the filesystem on. | +| name | string | yes | The storage identifier. | +| add_storage | boolean | no | Configure storage using the directory. | +| filesystem | string | no | The desired filesystem. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/disks/directory/{name} + +Unmounts the storage and removes the mount unit. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disk so it can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/disks/initgpt + +Initialize Disk with GPT + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | Block device name | +| uuid | string | no | UUID for the GPT table | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/disks/list + +List local disks. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| include-partitions | boolean | no | Also include partitions. | +| skipsmart | boolean | no | Skip smart checks. | +| type | string | no | Only list specific types of disks. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/disks/lvm + +List LVM Volume Groups + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/disks/lvm + +Create an LVM Volume Group + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| device | string | yes | The block device you want to create the volume group on | +| name | string | yes | The storage identifier. | +| add_storage | boolean | no | Configure storage using the Volume Group | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/disks/lvm/{name} + +Remove an LVM Volume Group. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disks so they can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/disks/lvmthin + +List LVM thinpools + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/disks/lvmthin + +Create an LVM thinpool + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| device | string | yes | The block device you want to create the thinpool on. | +| name | string | yes | The storage identifier. | +| add_storage | boolean | no | Configure storage using the thinpool. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/disks/lvmthin/{name} + +Remove an LVM thin pool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume-group | string | yes | The storage identifier. | +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disks so they can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/disks/smart + +Get SMART Health of a disk. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | Block device name | +| healthonly | boolean | no | If true returns only the health status | + +## Returns + +```json +{ + "properties": { + "attributes": { + "optional": 1, + "type": "array" + }, + "health": { + "type": "string" + }, + "text": { + "optional": 1, + "type": "string" + }, + "type": { + "optional": 1, + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# PUT /nodes/{node}/disks/wipedisk + +Wipe a disk or partition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | Block device name | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/disks/zfs + +List Zpools. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/disks/zfs + +Create a ZFS pool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| devices | string | yes | The block devices you want to create the zpool on. | +| name | string | yes | The storage identifier. | +| raidlevel | string | yes | The RAID level to use. | +| add_storage | boolean | no | Configure storage using the zpool. | +| ashift | integer | no | Pool sector size exponent. | +| compression | string | no | The compression algorithm to use. | +| draid-config | string | no | | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/disks/zfs/{name} + +Destroy a ZFS pool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disks so they can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/disks/zfs/{name} + +Get details about a zpool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/dns + +Read DNS settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/dns + +Write DNS settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| search | string | yes | Search domain for host-name lookup. | +| dns1 | string | no | First name server IP address. | +| dns2 | string | no | Second name server IP address. | +| dns3 | string | no | Third name server IP address. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/execute + +Execute multiple commands in order, root only. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| commands | string | yes | JSON encoded array of commands. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/firewall/log + +Read firewall log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| since | integer | no | Display log since this UNIX epoch. | +| start | integer | no | | +| until | integer | no | Display log until this UNIX epoch. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/firewall/options + +Get host firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable host firewall rules. | +| log_level_forward | string | no | Log level for forwarded traffic. | +| log_level_in | string | no | Log level for incoming traffic. | +| log_level_out | string | no | Log level for outgoing traffic. | +| log_nf_conntrack | boolean | no | Enable logging of conntrack information. | +| ndp | boolean | no | Enable NDP (Neighbor Discovery Protocol). | +| nf_conntrack_allow_invalid | boolean | no | Allow invalid packets on connection tracking. | +| nf_conntrack_helpers | string | no | Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp | +| nf_conntrack_max | integer | no | Maximum number of tracked connections. | +| nf_conntrack_tcp_timeout_established | integer | no | Conntrack established timeout. | +| nf_conntrack_tcp_timeout_syn_recv | integer | no | Conntrack syn recv timeout. | +| nftables | boolean | no | Enable nftables based firewall (tech preview) | +| nosmurfs | boolean | no | Enable SMURFS filter. | +| protection_synflood | boolean | no | Enable synflood protection | +| protection_synflood_burst | integer | no | Synflood protection rate burst by ip src. | +| protection_synflood_rate | integer | no | Synflood protection rate syn/sec by ip src. | +| smurf_log_level | string | no | Log level for SMURFS filter. | +| tcp_flags_log_level | string | no | Log level for illegal tcp flags filter. | +| tcpflags | boolean | no | Filter illegal combinations of TCP flags. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/hardware + +Index of hardware types + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{type}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/hardware/pci + +List local PCI devices. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pci-class-blacklist | string | no | A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b). | +| verbose | boolean | no | If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/hardware/pci/{pci-id-or-mapping} + +Index of available pci methods + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pci-id-or-mapping | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "method": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{method}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev + +List mediated device types for given PCI device. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pci-id-or-mapping | string | yes | The PCI ID or mapping to list the mdev types for. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/hardware/usb + +List local USB devices. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/hosts + +Get the content of /etc/hosts. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/hosts + +Write /etc/hosts. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| data | string | yes | The target content of /etc/hosts. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/journal + +Read Journal + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| endcursor | string | no | End before the given Cursor. Conflicts with 'until' | +| lastentries | integer | no | Limit to the last X lines. Conflicts with a range. | +| since | integer | no | Display all log since this UNIX epoch. Conflicts with 'startcursor'. | +| startcursor | string | no | Start after the given Cursor. Conflicts with 'since' | +| until | integer | no | Display all log until this UNIX epoch. Conflicts with 'endcursor'. | + +## Returns + +```json +{ + "items": { + "type": "string" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc + +LXC container index (per node). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list CTs where you have VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc + +Create or restore a container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ostemplate | string | yes | The OS template or backup file. | +| vmid | integer | yes | The (unique) ID of the VM. | +| arch | string | no | OS architecture type. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| cmode | string | no | 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). | +| console | boolean | no | Attach a console device (/dev/console) to the container. | +| cores | integer | no | The number of cores assigned to the container. A container can use all available cores by default. | +| cpulimit | number | no | Limit of CPU usage. NOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit. | +| cpuunits | integer | no | CPU weight for a container, will be clamped to [1, 10000] in cgroup v2. | +| debug | boolean | no | Try to be more verbose. For now this only enables debug log-level on start. | +| description | string | no | Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file. | +| dev[n] | string | no | Device to pass through to the container | +| entrypoint | string | no | Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH. | +| env | string | no | The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config. | +| features | string | no | Allow containers access to advanced features. | +| force | boolean | no | Allow to overwrite existing container. | +| ha-managed | boolean | no | Add the CT as a HA resource after it was created. | +| hookscript | string | no | Script that will be executed during various steps in the containers lifetime. | +| hostname | string | no | Set a host name for the container. | +| ignore-unpack-errors | boolean | no | Ignore errors when extracting the template. | +| lock | string | no | Lock/unlock the container. | +| memory | integer | no | Amount of RAM for the container in MB. | +| mp[n] | string | no | Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. | +| nameserver | string | no | Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| net[n] | string | no | Specifies network interfaces for the container. | +| onboot | boolean | no | Specifies whether a container will be started during system bootup. | +| ostype | string | no | 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. | +| password | string | no | Sets root password inside container. | +| pool | string | no | Add the VM to the specified pool. | +| protection | boolean | no | Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation. | +| restore | boolean | no | Mark this as restore task. | +| rootfs | string | no | Use volume as container root. | +| searchdomain | string | no | Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| ssh-public-keys | string | no | Setup public SSH keys (one key per line, OpenSSH format). | +| start | boolean | no | Start the CT after its creation finished successfully. | +| startup | string | no | 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. | +| storage | string | no | Default Storage. | +| swap | integer | no | Amount of SWAP for the container in MB. | +| tags | string | no | Tags of the Container. This is only meta information. | +| template | boolean | no | Enable/disable Template. | +| timezone | string | no | 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 | +| tty | integer | no | Specify the number of tty available to the container | +| unique | boolean | no | Assign a unique random ethernet address. | +| unprivileged | boolean | no | 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.) | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/lxc/{vmid} + +Destroy the container (also delete all uses files). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| destroy-unreferenced-disks | boolean | no | If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config. | +| force | boolean | no | Force destroy, even if running. | +| purge | boolean | no | Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid} + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/clone + +Create a container clone/copy + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| newid | integer | yes | VMID for the clone. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| description | string | no | Description for the new CT. | +| full | boolean | no | 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. | +| hostname | string | no | Set a hostname for the new CT. | +| pool | string | no | Add the new CT to the specified pool. | +| snapname | string | no | The name of the snapshot. | +| storage | string | no | Target storage for full clone. | +| target | string | no | Target node. Only allowed if the original VM is on shared storage. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/config + +Get container configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| current | boolean | no | Get current values (instead of pending values). | +| snapshot | string | no | Fetch config values from given snapshot. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/config + +Set container options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| arch | string | no | OS architecture type. | +| cmode | string | no | 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). | +| console | boolean | no | Attach a console device (/dev/console) to the container. | +| cores | integer | no | The number of cores assigned to the container. A container can use all available cores by default. | +| cpulimit | number | no | Limit of CPU usage. NOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit. | +| cpuunits | integer | no | CPU weight for a container, will be clamped to [1, 10000] in cgroup v2. | +| debug | boolean | no | Try to be more verbose. For now this only enables debug log-level on start. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file. | +| dev[n] | string | no | Device to pass through to the container | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| entrypoint | string | no | Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH. | +| env | string | no | The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config. | +| features | string | no | Allow containers access to advanced features. | +| hookscript | string | no | Script that will be executed during various steps in the containers lifetime. | +| hostname | string | no | Set a host name for the container. | +| lock | string | no | Lock/unlock the container. | +| memory | integer | no | Amount of RAM for the container in MB. | +| mp[n] | string | no | Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. | +| nameserver | string | no | Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| net[n] | string | no | Specifies network interfaces for the container. | +| onboot | boolean | no | Specifies whether a container will be started during system bootup. | +| ostype | string | no | 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. | +| protection | boolean | no | Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation. | +| revert | string | no | Revert a pending change. | +| rootfs | string | no | Use volume as container root. | +| searchdomain | string | no | Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| startup | string | no | 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. | +| swap | integer | no | Amount of SWAP for the container in MB. | +| tags | string | no | Tags of the Container. This is only meta information. | +| template | boolean | no | Enable/disable Template. | +| timezone | string | no | 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 | +| tty | integer | no | Specify the number of tty available to the container | +| unprivileged | boolean | no | 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.) | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/feature + +Check if feature for virtual machine is available. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| feature | string | yes | Feature to check. | +| snapname | string | no | The name of the snapshot. | + +## Returns + +```json +{ + "properties": { + "hasFeature": { + "type": "boolean" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/firewall/aliases + +List aliases + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/aliases + +Create IP or Network Alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | Alias name. | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/lxc/{vmid}/firewall/aliases/{name} + +Remove IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/aliases/{name} + +Read alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/aliases/{name} + +Update IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing alias. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/firewall/ipset + +List IPSets + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/ipset + +Create new IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name} + +Delete IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Delete all members of the IPSet, if there are any. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/ipset/{name} + +List IPSet content + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/ipset/{name} + +Add IP or Network to IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr} + +Remove IP or Network from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr} + +Read IP or Network settings from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr} + +Update IP or Network settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/firewall/log + +Read firewall log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| since | integer | no | Display log since this UNIX epoch. | +| start | integer | no | | +| until | integer | no | Display log until this UNIX epoch. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/firewall/options + +Get VM firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| dhcp | boolean | no | Enable DHCP. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable/disable firewall rules. | +| ipfilter | boolean | no | 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. | +| log_level_in | string | no | Log level for incoming traffic. | +| log_level_out | string | no | Log level for outgoing traffic. | +| macfilter | boolean | no | Enable/disable MAC address filter. | +| ndp | boolean | no | Enable NDP (Neighbor Discovery Protocol). | +| policy_in | string | no | Input policy. | +| policy_out | string | no | Output policy. | +| radv | boolean | no | Allow sending Router Advertisement. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/firewall/refs + +Lists possible IPSet/Alias reference which are allowed in source/dest properties. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list references of specified type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/lxc/{vmid}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/interfaces + +Get IP addresses of the specified container interface. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/migrate + +Get preconditions for migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | no | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/migrate + +Migrate the container to another node. Creates a new migration task. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| online | boolean | no | Use online/live migration. | +| restart | boolean | no | Use restart migration | +| target-storage | string | no | 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. | +| timeout | integer | no | Timeout in seconds for shutdown for restart migration | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/move_volume + +Move a rootfs-/mp-volume to a different storage or to a different container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume | string | yes | Volume which will be moved. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | Delete the original volume after successful copy. By default the original is kept as an unused volume entry. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 " . "digest. This can be used to prevent concurrent modifications. | +| storage | string | no | Target Storage. | +| target-digest | string | no | Prevent changes if current configuration file of the target " . "container has a different SHA1 digest. This can be used to prevent " . "concurrent modifications. | +| target-vmid | integer | no | The (unique) ID of the VM. | +| target-volume | string | no | The config key the volume will be moved to. Default is the source volume key. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/mtunnel + +Migration tunnel endpoint - only for internal use by CT migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| bridges | string | no | List of network bridges to check availability. Will be checked again for actually used bridges during migration. | +| storages | string | no | List of storages to check permission and availability. Will be checked again for all actually used storages during migration. | + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "socket": { + "type": "string" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/mtunnelwebsocket + +Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| socket | string | yes | unix socket to forward to | +| ticket | string | yes | ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command | + +## Returns + +```json +{ + "properties": { + "port": { + "optional": 1, + "type": "string" + }, + "socket": { + "optional": 1, + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/pending + +Get container configuration, including pending changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/remote_migrate + +Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target-bridge | string | yes | 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. | +| target-endpoint | string | yes | Remote target endpoint | +| target-storage | string | yes | 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. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | 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. | +| online | boolean | no | Use online/live migration. | +| restart | boolean | no | Use restart migration | +| target-vmid | integer | no | The (unique) ID of the VM. | +| timeout | integer | no | Timeout in seconds for shutdown for restart migration | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# PUT /nodes/{node}/lxc/{vmid}/resize + +Resize a container mount point. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | The disk you want to resize. | +| size | string | yes | 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. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/rrd + +Read VM RRD statistics (returns PNG) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/rrddata + +Read VM RRD statistics + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/snapshot + +List all snapshots. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/snapshot + +Snapshot a container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| snapname | string | yes | The name of the snapshot. | +| description | string | no | A textual description or comment. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/lxc/{vmid}/snapshot/{snapname} + +Delete a LXC snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | For removal from config file, even if removing disk snapshots fails. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/snapshot/{snapname} + +snapshot_cmd_idx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{cmd}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config + +Get snapshot configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config + +Update snapshot metadata. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| description | string | no | A textual description or comment. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback + +Rollback LXC state to specified snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| start | boolean | no | Whether the container should get started after rolling back successfully | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/spiceproxy + +Returns a SPICE configuration to connect to the CT. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| proxy | string | no | 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). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/status + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/status/current + +Get virtual machine status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/status/reboot + +Reboot the container by shutting it down, and starting it again. Applies pending changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeout | integer | no | Wait maximal timeout seconds for the shutdown. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/status/resume + +Resume the container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/status/shutdown + +Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| forceStop | boolean | no | Make sure the Container stops. | +| timeout | integer | no | Wait maximal timeout seconds. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/status/start + +Start the container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| debug | boolean | no | If set, enables very verbose debug log-level on start. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/status/stop + +Stop the container. This will abruptly stop all processes running in the container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| overrule-shutdown | boolean | no | Try to abort active 'vzshutdown' tasks before stopping. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/status/suspend + +Suspend the container. This is experimental. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/template + +Create a Template. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description": "You need 'VM.Allocate' permissions on /vms/{vmid}" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/termproxy + +Creates a TCP proxy connection. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "port": { + "type": "integer" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + }, + "user": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# POST /nodes/{node}/lxc/{vmid}/vncproxy + +Creates a TCP VNC proxy connections. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| height | integer | no | sets the height of the console in pixels. | +| websocket | boolean | no | use websocket instead of standard VNC. | +| width | integer | no | sets the width of the console in pixels. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/lxc/{vmid}/vncwebsocket + +Opens a websocket for VNC traffic. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | Port number returned by previous vncproxy call. | +| vncticket | string | yes | Ticket from previous call to vncproxy. | + +## Returns + +```json +{ + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/migrateall + +Migrate all VMs and Containers. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| max-workers | integer | no | Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set! | +| maxworkers | integer | no | 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. | +| vms | string | no | Only consider Guests with these IDs. | +| with-local-disks | boolean | no | Enable live storage migration for local disk | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/netstat + +Read tap/vm network device interface counters + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/network + +Revert network configuration changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/network + +List available networks + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list specific interface types. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/network + +Create network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| type | string | yes | Network interface type | +| address | string | no | IP address. | +| address6 | string | no | IP address. | +| autostart | boolean | no | Automatically start interface on boot. | +| bond_mode | string | no | Bonding mode. | +| bond_xmit_hash_policy | string | no | Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. | +| bond-primary | string | no | Specify the primary interface for active-backup bond. | +| bridge_ports | string | no | Specify the interfaces you want to add to your bridge. | +| bridge_vids | string | no | Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware. | +| bridge_vlan_aware | boolean | no | Enable bridge vlan support. | +| cidr | string | no | IPv4 CIDR. | +| cidr6 | string | no | IPv6 CIDR. | +| comments | string | no | Comments | +| comments6 | string | no | Comments | +| gateway | string | no | Default gateway address. | +| gateway6 | string | no | Default ipv6 gateway address. | +| mtu | integer | no | MTU. | +| netmask | string | no | Network mask. | +| netmask6 | integer | no | Network mask. | +| ovs_bonds | string | no | Specify the interfaces used by the bonding device. | +| ovs_bridge | string | no | The OVS bridge associated with a OVS port. This is required when you create an OVS port. | +| ovs_options | string | no | OVS interface options. | +| ovs_ports | string | no | Specify the interfaces you want to add to your bridge. | +| ovs_tag | integer | no | Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond) | +| slaves | string | no | Specify the interfaces used by the bonding device. | +| vlan-id | integer | no | vlan-id for a custom named vlan interface (ifupdown2 only). | +| vlan-raw-device | string | no | Specify the raw interface for the vlan interface. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/network + +Reload network configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| regenerate-frr | boolean | no | Whether FRR config generation should get skipped or not. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/network/{iface} + +Delete network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/network/{iface} + +Read network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "properties": { + "method": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/network/{iface} + +Update network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | Network interface type | +| address | string | no | IP address. | +| address6 | string | no | IP address. | +| autostart | boolean | no | Automatically start interface on boot. | +| bond_mode | string | no | Bonding mode. | +| bond_xmit_hash_policy | string | no | Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. | +| bond-primary | string | no | Specify the primary interface for active-backup bond. | +| bridge_ports | string | no | Specify the interfaces you want to add to your bridge. | +| bridge_vids | string | no | Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware. | +| bridge_vlan_aware | boolean | no | Enable bridge vlan support. | +| cidr | string | no | IPv4 CIDR. | +| cidr6 | string | no | IPv6 CIDR. | +| comments | string | no | Comments | +| comments6 | string | no | Comments | +| delete | string | no | A list of settings you want to delete. | +| gateway | string | no | Default gateway address. | +| gateway6 | string | no | Default ipv6 gateway address. | +| mtu | integer | no | MTU. | +| netmask | string | no | Network mask. | +| netmask6 | integer | no | Network mask. | +| ovs_bonds | string | no | Specify the interfaces used by the bonding device. | +| ovs_bridge | string | no | The OVS bridge associated with a OVS port. This is required when you create an OVS port. | +| ovs_options | string | no | OVS interface options. | +| ovs_ports | string | no | Specify the interfaces you want to add to your bridge. | +| ovs_tag | integer | no | Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond) | +| slaves | string | no | Specify the interfaces used by the bonding device. | +| vlan-id | integer | no | vlan-id for a custom named vlan interface (ifupdown2 only). | +| vlan-raw-device | string | no | Specify the raw interface for the vlan interface. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu + +Virtual machine index (per node). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| full | boolean | no | Determine the full status of active VMs. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list VMs where you have VM.Audit permissions on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu + +Create or restore a virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vmid | integer | yes | The (unique) ID of the VM. | +| acpi | boolean | no | Enable/disable ACPI. | +| affinity | string | no | List of host cores used to execute guest processes, for example: 0,5,8-11 | +| agent | string | no | Enable/disable communication with the QEMU Guest Agent and its properties. | +| allow-ksm | boolean | no | Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging). | +| amd-sev | string | no | Secure Encrypted Virtualization (SEV) features by AMD CPUs | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | +| archive | string | no | 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. | +| args | string | no | Arbitrary arguments passed to kvm. | +| audio0 | string | no | Configure a audio device, useful in combination with QXL/Spice. | +| autostart | boolean | no | Automatic restart after crash (currently ignored). | +| balloon | integer | no | 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. | +| bios | string | no | Select BIOS implementation. | +| boot | string | no | Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated. | +| bootdisk | string | no | Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| cdrom | string | no | This is an alias for option -ide2 | +| cicustom | string | no | cloud-init: Specify custom files to replace the automatically generated ones at start. | +| cipassword | string | no | 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. | +| citype | string | no | 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. | +| ciupgrade | boolean | no | cloud-init: do an automatic package upgrade after the first boot. | +| ciuser | string | no | cloud-init: User name to change ssh keys and password for instead of the image's configured default user. | +| cores | integer | no | The number of cores per socket. | +| cpu | string | no | Emulated CPU type. | +| cpulimit | number | no | Limit of CPU usage. | +| cpuunits | integer | no | CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2. | +| description | string | no | Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file. | +| efidisk0 | string | no | 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. | +| force | boolean | no | Allow to overwrite existing VM. | +| freeze | boolean | no | Freeze CPU at startup (use 'c' monitor command to start execution). | +| ha-managed | boolean | no | Add the VM as a HA resource after it was created. | +| hookscript | string | no | Script that will be executed during various steps in the vms lifetime. | +| hostpci[n] | string | no | Map host PCI devices into guest. | +| hotplug | string | no | 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. | +| hugepages | string | no | Enables hugepages memory. Sets 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. | +| ide[n] | string | no | 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. | +| import-working-storage | string | no | A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage. | +| intel-tdx | string | no | Trusted Domain Extension (TDX) features by Intel CPUs | +| ipconfig[n] | string | no | cloud-init: Specify IP addresses and gateways for the corresponding interface. IP addresses use CIDR notation, gateways are optional but need an IP of the same type specified. The special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit gateway should be provided. For IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires cloud-init 19.4 or newer. If cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using dhcp on IPv4. | +| ivshmem | string | no | Inter-VM shared memory. Useful for direct communication between VMs, or to the host. | +| keephugepages | boolean | no | Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts. | +| keyboard | string | no | Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. | +| kvm | boolean | no | Enable/disable KVM hardware virtualization. | +| live-restore | boolean | no | Start the VM immediately while importing or restoring in the background. | +| localtime | boolean | no | Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS. | +| lock | string | no | Lock/unlock the VM. | +| machine | string | no | Specify the QEMU machine. | +| memory | string | no | Memory properties. | +| migrate_downtime | number | no | 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). | +| migrate_speed | integer | no | Set maximum speed (in MB/s) for migrations. Value 0 is no limit. | +| name | string | no | Set a name for the VM. Only used on the configuration web interface. | +| nameserver | string | no | 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. | +| net[n] | string | no | Specify network devices. | +| numa | boolean | no | Enable/disable NUMA. | +| numa[n] | string | no | NUMA topology. | +| onboot | boolean | no | Specifies whether a VM will be started during system bootup. | +| ostype | string | no | Specify guest operating system. | +| parallel[n] | string | no | Map host parallel devices (n is 0 to 2). | +| pool | string | no | Add the VM to the specified pool. | +| protection | boolean | no | Sets the protection flag of the VM. This will disable the remove VM and remove disk operations. | +| reboot | boolean | no | Allow reboot. If set to '0' the VM exit on reboot. | +| rng0 | string | no | Configure a VirtIO-based Random Number Generator. | +| sata[n] | string | no | 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. | +| scsi[n] | string | no | 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. | +| scsihw | string | no | SCSI controller model | +| searchdomain | string | no | 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. | +| serial[n] | string | no | Create a serial device inside the VM (n is 0 to 3) | +| shares | integer | no | 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. | +| smbios1 | string | no | Specify SMBIOS type 1 fields. | +| smp | integer | no | The number of CPUs. Please use option -sockets instead. | +| sockets | integer | no | The number of CPU sockets. | +| spice_enhancements | string | no | Configure additional enhancements for SPICE. | +| sshkeys | string | no | cloud-init: Setup public SSH keys (one key per line, OpenSSH format). | +| start | boolean | no | Start VM after it was created successfully. | +| startdate | string | no | 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'. | +| startup | string | no | 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. | +| storage | string | no | Default storage. | +| tablet | boolean | no | Enable/disable the USB tablet device. | +| tags | string | no | Tags of the VM. This is only meta information. | +| tdf | boolean | no | Enable/disable time drift fix. | +| template | boolean | no | Enable/disable Template. | +| tpmstate0 | string | no | 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. | +| unique | boolean | no | Assign a unique random ethernet address. | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | +| usb[n] | string | no | 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). | +| vcpus | integer | no | Number of hotplugged vcpus. | +| vga | string | no | Configure the VGA hardware. | +| virtio[n] | string | no | 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. | +| virtiofs[n] | string | no | Configuration for sharing a directory between host and guest using Virtio-fs. | +| vmgenid | string | no | Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly. | +| vmstatestorage | string | no | Default storage for VM state volumes/files. | +| watchdog | string | no | Create a virtual hardware watchdog device. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/qemu/{vmid} + +Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| destroy-unreferenced-disks | boolean | no | If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages. | +| purge | boolean | no | Remove VMID from configurations, like backup & replication jobs and HA. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid} + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent + +QEMU Guest Agent command index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns the list of QEMU Guest Agent commands", + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/agent + +Execute QEMU Guest Agent commands. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | string | yes | The QGA command. | + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/exec + +Executes the given command in the vm via the guest-agent and returns an object with the pid. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | array | yes | The command as a list of program + arguments. | +| input-data | string | no | Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'. | + +## Returns + +```json +{ + "properties": { + "pid": { + "description": "The PID of the process started by the guest-agent.", + "type": "integer" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/exec-status + +Gets the status of the given pid started by the guest-agent + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pid | integer | yes | The PID to query | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/file-read + +Reads the given file via guest agent. Is limited to 16777216 bytes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| file | string | yes | The path to the file | +| count | integer | no | Number of bytes to read. | +| decode | boolean | no | 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. | +| offset | integer | no | Offset to start reading at | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileRead", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/file-write + +Writes the given file via guest agent. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | yes | The content to write into the file. | +| file | string | yes | The path to the file. | +| encode | boolean | no | If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileWrite", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze + +Execute fsfreeze-freeze. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-status + +Execute fsfreeze-status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw + +Execute fsfreeze-thaw. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/fstrim + +Execute fstrim. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-fsinfo + +Execute get-fsinfo. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-host-name + +Execute get-host-name. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-memory-block-info + +Execute get-memory-block-info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-memory-blocks + +Execute get-memory-blocks. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-osinfo + +Execute get-osinfo. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-time + +Execute get-time. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-timezone + +Execute get-timezone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-users + +Execute get-users. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/get-vcpus + +Execute get-vcpus. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/info + +Execute info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces + +Execute network-get-interfaces. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/ping + +Execute ping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/set-user-password + +Sets the password for the given user to the given password + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | The new password. | +| username | string | yes | The user to set the password for. | +| crypted | boolean | no | set to 1 if the password has already been passed through crypt() | + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/shutdown + +Execute shutdown. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/suspend-disk + +Execute suspend-disk. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/suspend-hybrid + +Execute suspend-hybrid. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/agent/suspend-ram + +Execute suspend-ram. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/clone + +Create a copy of virtual machine/template. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| newid | integer | yes | VMID for the clone. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| description | string | no | Description for the new VM. | +| format | string | no | Target format for file storage. Only valid for full clone. | +| full | boolean | no | 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. | +| name | string | no | Set a name for the new VM. | +| pool | string | no | Add the new VM to the specified pool. | +| snapname | string | no | The name of the snapshot. | +| storage | string | no | Target storage for full clone. | +| target | string | no | Target node. Only allowed if the original VM is on shared storage. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/cloudinit + +Get the cloudinit configuration with both current and pending values. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/cloudinit + +Regenerate and change cloudinit config drive. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Cloudinit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/cloudinit/dump + +Get automatically generated cloudinit config. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | Config type. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/config + +Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| current | boolean | no | Get current values (instead of pending values). | +| snapshot | string | no | Fetch config values from given snapshot. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/config + +Set virtual machine options (asynchronous API). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acpi | boolean | no | Enable/disable ACPI. | +| affinity | string | no | List of host cores used to execute guest processes, for example: 0,5,8-11 | +| agent | string | no | Enable/disable communication with the QEMU Guest Agent and its properties. | +| allow-ksm | boolean | no | Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging). | +| amd-sev | string | no | Secure Encrypted Virtualization (SEV) features by AMD CPUs | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | +| args | string | no | Arbitrary arguments passed to kvm. | +| audio0 | string | no | Configure a audio device, useful in combination with QXL/Spice. | +| autostart | boolean | no | Automatic restart after crash (currently ignored). | +| background_delay | integer | no | Time to wait for the task to finish. We return 'null' if the task finish within that time. | +| balloon | integer | no | 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. | +| bios | string | no | Select BIOS implementation. | +| boot | string | no | Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated. | +| bootdisk | string | no | Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead. | +| cdrom | string | no | This is an alias for option -ide2 | +| cicustom | string | no | cloud-init: Specify custom files to replace the automatically generated ones at start. | +| cipassword | string | no | 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. | +| citype | string | no | 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. | +| ciupgrade | boolean | no | cloud-init: do an automatic package upgrade after the first boot. | +| ciuser | string | no | cloud-init: User name to change ssh keys and password for instead of the image's configured default user. | +| cores | integer | no | The number of cores per socket. | +| cpu | string | no | Emulated CPU type. | +| cpulimit | number | no | Limit of CPU usage. | +| cpuunits | integer | no | CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| efidisk0 | string | no | 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. | +| force | boolean | no | 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. | +| freeze | boolean | no | Freeze CPU at startup (use 'c' monitor command to start execution). | +| hookscript | string | no | Script that will be executed during various steps in the vms lifetime. | +| hostpci[n] | string | no | Map host PCI devices into guest. | +| hotplug | string | no | 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. | +| hugepages | string | no | Enables hugepages memory. Sets 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. | +| ide[n] | string | no | 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. | +| import-working-storage | string | no | A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage. | +| intel-tdx | string | no | Trusted Domain Extension (TDX) features by Intel CPUs | +| ipconfig[n] | string | no | cloud-init: Specify IP addresses and gateways for the corresponding interface. IP addresses use CIDR notation, gateways are optional but need an IP of the same type specified. The special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit gateway should be provided. For IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires cloud-init 19.4 or newer. If cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using dhcp on IPv4. | +| ivshmem | string | no | Inter-VM shared memory. Useful for direct communication between VMs, or to the host. | +| keephugepages | boolean | no | Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts. | +| keyboard | string | no | Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. | +| kvm | boolean | no | Enable/disable KVM hardware virtualization. | +| localtime | boolean | no | Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS. | +| lock | string | no | Lock/unlock the VM. | +| machine | string | no | Specify the QEMU machine. | +| memory | string | no | Memory properties. | +| migrate_downtime | number | no | 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). | +| migrate_speed | integer | no | Set maximum speed (in MB/s) for migrations. Value 0 is no limit. | +| name | string | no | Set a name for the VM. Only used on the configuration web interface. | +| nameserver | string | no | 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. | +| net[n] | string | no | Specify network devices. | +| numa | boolean | no | Enable/disable NUMA. | +| numa[n] | string | no | NUMA topology. | +| onboot | boolean | no | Specifies whether a VM will be started during system bootup. | +| ostype | string | no | Specify guest operating system. | +| parallel[n] | string | no | Map host parallel devices (n is 0 to 2). | +| protection | boolean | no | Sets the protection flag of the VM. This will disable the remove VM and remove disk operations. | +| reboot | boolean | no | Allow reboot. If set to '0' the VM exit on reboot. | +| revert | string | no | Revert a pending change. | +| rng0 | string | no | Configure a VirtIO-based Random Number Generator. | +| sata[n] | string | no | 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. | +| scsi[n] | string | no | 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. | +| scsihw | string | no | SCSI controller model | +| searchdomain | string | no | 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. | +| serial[n] | string | no | Create a serial device inside the VM (n is 0 to 3) | +| shares | integer | no | 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. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| smbios1 | string | no | Specify SMBIOS type 1 fields. | +| smp | integer | no | The number of CPUs. Please use option -sockets instead. | +| sockets | integer | no | The number of CPU sockets. | +| spice_enhancements | string | no | Configure additional enhancements for SPICE. | +| sshkeys | string | no | cloud-init: Setup public SSH keys (one key per line, OpenSSH format). | +| startdate | string | no | 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'. | +| startup | string | no | 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. | +| tablet | boolean | no | Enable/disable the USB tablet device. | +| tags | string | no | Tags of the VM. This is only meta information. | +| tdf | boolean | no | Enable/disable time drift fix. | +| template | boolean | no | Enable/disable Template. | +| tpmstate0 | string | no | 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. | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | +| usb[n] | string | no | 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). | +| vcpus | integer | no | Number of hotplugged vcpus. | +| vga | string | no | Configure the VGA hardware. | +| virtio[n] | string | no | 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. | +| virtiofs[n] | string | no | Configuration for sharing a directory between host and guest using Virtio-fs. | +| vmgenid | string | no | Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly. | +| vmstatestorage | string | no | Default storage for VM state volumes/files. | +| watchdog | string | no | Create a virtual hardware watchdog device. | + +## Returns + +```json +{ + "optional": 1, + "type": "string" +} +``` + +## Permissions + +```json +{ + "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 + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/config + +Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acpi | boolean | no | Enable/disable ACPI. | +| affinity | string | no | List of host cores used to execute guest processes, for example: 0,5,8-11 | +| agent | string | no | Enable/disable communication with the QEMU Guest Agent and its properties. | +| allow-ksm | boolean | no | Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging). | +| amd-sev | string | no | Secure Encrypted Virtualization (SEV) features by AMD CPUs | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | +| args | string | no | Arbitrary arguments passed to kvm. | +| audio0 | string | no | Configure a audio device, useful in combination with QXL/Spice. | +| autostart | boolean | no | Automatic restart after crash (currently ignored). | +| balloon | integer | no | 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. | +| bios | string | no | Select BIOS implementation. | +| boot | string | no | Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated. | +| bootdisk | string | no | Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead. | +| cdrom | string | no | This is an alias for option -ide2 | +| cicustom | string | no | cloud-init: Specify custom files to replace the automatically generated ones at start. | +| cipassword | string | no | 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. | +| citype | string | no | 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. | +| ciupgrade | boolean | no | cloud-init: do an automatic package upgrade after the first boot. | +| ciuser | string | no | cloud-init: User name to change ssh keys and password for instead of the image's configured default user. | +| cores | integer | no | The number of cores per socket. | +| cpu | string | no | Emulated CPU type. | +| cpulimit | number | no | Limit of CPU usage. | +| cpuunits | integer | no | CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| efidisk0 | string | no | 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. | +| force | boolean | no | 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. | +| freeze | boolean | no | Freeze CPU at startup (use 'c' monitor command to start execution). | +| hookscript | string | no | Script that will be executed during various steps in the vms lifetime. | +| hostpci[n] | string | no | Map host PCI devices into guest. | +| hotplug | string | no | 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. | +| hugepages | string | no | Enables hugepages memory. Sets 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. | +| ide[n] | string | no | 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. | +| intel-tdx | string | no | Trusted Domain Extension (TDX) features by Intel CPUs | +| ipconfig[n] | string | no | cloud-init: Specify IP addresses and gateways for the corresponding interface. IP addresses use CIDR notation, gateways are optional but need an IP of the same type specified. The special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit gateway should be provided. For IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires cloud-init 19.4 or newer. If cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using dhcp on IPv4. | +| ivshmem | string | no | Inter-VM shared memory. Useful for direct communication between VMs, or to the host. | +| keephugepages | boolean | no | Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts. | +| keyboard | string | no | Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. | +| kvm | boolean | no | Enable/disable KVM hardware virtualization. | +| localtime | boolean | no | Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS. | +| lock | string | no | Lock/unlock the VM. | +| machine | string | no | Specify the QEMU machine. | +| memory | string | no | Memory properties. | +| migrate_downtime | number | no | 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). | +| migrate_speed | integer | no | Set maximum speed (in MB/s) for migrations. Value 0 is no limit. | +| name | string | no | Set a name for the VM. Only used on the configuration web interface. | +| nameserver | string | no | 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. | +| net[n] | string | no | Specify network devices. | +| numa | boolean | no | Enable/disable NUMA. | +| numa[n] | string | no | NUMA topology. | +| onboot | boolean | no | Specifies whether a VM will be started during system bootup. | +| ostype | string | no | Specify guest operating system. | +| parallel[n] | string | no | Map host parallel devices (n is 0 to 2). | +| protection | boolean | no | Sets the protection flag of the VM. This will disable the remove VM and remove disk operations. | +| reboot | boolean | no | Allow reboot. If set to '0' the VM exit on reboot. | +| revert | string | no | Revert a pending change. | +| rng0 | string | no | Configure a VirtIO-based Random Number Generator. | +| sata[n] | string | no | 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. | +| scsi[n] | string | no | 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. | +| scsihw | string | no | SCSI controller model | +| searchdomain | string | no | 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. | +| serial[n] | string | no | Create a serial device inside the VM (n is 0 to 3) | +| shares | integer | no | 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. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| smbios1 | string | no | Specify SMBIOS type 1 fields. | +| smp | integer | no | The number of CPUs. Please use option -sockets instead. | +| sockets | integer | no | The number of CPU sockets. | +| spice_enhancements | string | no | Configure additional enhancements for SPICE. | +| sshkeys | string | no | cloud-init: Setup public SSH keys (one key per line, OpenSSH format). | +| startdate | string | no | 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'. | +| startup | string | no | 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. | +| tablet | boolean | no | Enable/disable the USB tablet device. | +| tags | string | no | Tags of the VM. This is only meta information. | +| tdf | boolean | no | Enable/disable time drift fix. | +| template | boolean | no | Enable/disable Template. | +| tpmstate0 | string | no | 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. | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | +| usb[n] | string | no | 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). | +| vcpus | integer | no | Number of hotplugged vcpus. | +| vga | string | no | Configure the VGA hardware. | +| virtio[n] | string | no | 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. | +| virtiofs[n] | string | no | Configuration for sharing a directory between host and guest using Virtio-fs. | +| vmgenid | string | no | Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly. | +| vmstatestorage | string | no | Default storage for VM state volumes/files. | +| watchdog | string | no | Create a virtual hardware watchdog device. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/dbus-vmstate + +Control the dbus-vmstate helper for a given running VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Action to perform on the DBus VMState helper. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/feature + +Check if feature for virtual machine is available. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| feature | string | yes | Feature to check. | +| snapname | string | no | The name of the snapshot. | + +## Returns + +```json +{ + "properties": { + "hasFeature": { + "type": "boolean" + }, + "nodes": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/firewall/aliases + +List aliases + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/aliases + +Create IP or Network Alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | Alias name. | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/qemu/{vmid}/firewall/aliases/{name} + +Remove IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/aliases/{name} + +Read alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/aliases/{name} + +Update IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing alias. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/firewall/ipset + +List IPSets + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/ipset + +Create new IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name} + +Delete IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Delete all members of the IPSet, if there are any. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/ipset/{name} + +List IPSet content + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/ipset/{name} + +Add IP or Network to IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr} + +Remove IP or Network from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr} + +Read IP or Network settings from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr} + +Update IP or Network settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/firewall/log + +Read firewall log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| since | integer | no | Display log since this UNIX epoch. | +| start | integer | no | | +| until | integer | no | Display log until this UNIX epoch. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/firewall/options + +Get VM firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| dhcp | boolean | no | Enable DHCP. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable/disable firewall rules. | +| ipfilter | boolean | no | 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. | +| log_level_in | string | no | Log level for incoming traffic. | +| log_level_out | string | no | Log level for outgoing traffic. | +| macfilter | boolean | no | Enable/disable MAC address filter. | +| ndp | boolean | no | Enable NDP (Neighbor Discovery Protocol). | +| policy_in | string | no | Input policy. | +| policy_out | string | no | Output policy. | +| radv | boolean | no | Allow sending Router Advertisement. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/firewall/refs + +Lists possible IPSet/Alias reference which are allowed in source/dest properties. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list references of specified type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/qemu/{vmid}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/migrate + +Get preconditions for migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | no | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/migrate + +Migrate virtual machine. Creates a new migration task. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| force | boolean | no | Allow to migrate VMs which use local devices. Only root may use this option. | +| migration_network | string | no | CIDR of the (sub) network that is used for migration. | +| migration_type | string | no | Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. | +| online | boolean | no | Use online/live migration if VM is running. Ignored if VM is stopped. | +| targetstorage | string | no | 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. | +| with-conntrack-state | boolean | no | Whether to migrate conntrack entries for running VMs. | +| with-local-disks | boolean | no | Enable live storage migration for local disk | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/monitor + +Execute QEMU monitor commands. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | string | yes | The monitor command. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/move_disk + +Move volume to different storage or to a different VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | The disk you want to move. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | Delete the original disk after successful copy. By default the original disk is kept as unused disk. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| format | string | no | Target Format. | +| storage | string | no | Target storage. | +| target-digest | string | no | Prevent changes if the current config file of the target VM has a different SHA1 digest. This can be used to detect concurrent modifications. | +| target-disk | string | no | The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key. | +| target-vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/mtunnel + +Migration tunnel endpoint - only for internal use by VM migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| bridges | string | no | List of network bridges to check availability. Will be checked again for actually used bridges during migration. | +| storages | string | no | List of storages to check permission and availability. Will be checked again for all actually used storages during migration. | + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "socket": { + "type": "string" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/mtunnelwebsocket + +Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| socket | string | yes | unix socket to forward to | +| ticket | string | yes | ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command | + +## Returns + +```json +{ + "properties": { + "port": { + "optional": 1, + "type": "string" + }, + "socket": { + "optional": 1, + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/pending + +Get the virtual machine configuration with both current and pending values. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/remote_migrate + +Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target-bridge | string | yes | 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. | +| target-endpoint | string | yes | Remote target endpoint | +| target-storage | string | yes | 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. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | 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. | +| online | boolean | no | Use online/live migration if VM is running. Ignored if VM is stopped. | +| target-vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# PUT /nodes/{node}/qemu/{vmid}/resize + +Extend volume size. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | The disk you want to resize. | +| size | string | yes | 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. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/rrd + +Read VM RRD statistics (returns PNG) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/rrddata + +Read VM RRD statistics + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# PUT /nodes/{node}/qemu/{vmid}/sendkey + +Send key event to virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| key | string | yes | The key (qemu monitor encoding). | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/snapshot + +List all snapshots. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/snapshot + +Snapshot a VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| snapname | string | yes | The name of the snapshot. | +| description | string | no | A textual description or comment. | +| vmstate | boolean | no | Save the vmstate | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/qemu/{vmid}/snapshot/{snapname} + +Delete a VM snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | For removal from config file, even if removing disk snapshots fails. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/snapshot/{snapname} + +snapshot_cmd_idx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{cmd}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config + +Get snapshot configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config + +Update snapshot metadata. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| description | string | no | A textual description or comment. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback + +Rollback VM state to specified snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| start | boolean | no | Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.) | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/spiceproxy + +Returns a SPICE configuration to connect to the VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| proxy | string | no | 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). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/status + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/status/current + +Get virtual machine status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/status/reboot + +Reboot the VM by shutting it down, and starting it again. Applies pending changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeout | integer | no | Wait maximal timeout seconds for the shutdown. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/status/reset + +Reset virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/status/resume + +Resume virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| nocheck | boolean | no | | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/status/shutdown + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| forceStop | boolean | no | Make sure the VM stops. | +| keepActive | boolean | no | Do not deactivate storage volumes. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| timeout | integer | no | Wait maximal timeout seconds. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/status/start + +Start virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force-cpu | string | no | Override QEMU's -cpu argument with the given string. | +| machine | string | no | Specify the QEMU machine. | +| migratedfrom | string | no | The cluster node name. | +| migration_network | string | no | CIDR of the (sub) network that is used for migration. | +| migration_type | string | no | Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. | +| nets-host-mtu | string | no | 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. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| stateuri | string | no | Some command save/restore state from this location. | +| targetstorage | string | no | 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. | +| timeout | integer | no | Wait maximal timeout seconds. | +| with-conntrack-state | boolean | no | Whether to migrate conntrack entries for running VMs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/status/stop + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| keepActive | boolean | no | Do not deactivate storage volumes. | +| migratedfrom | string | no | The cluster node name. | +| overrule-shutdown | boolean | no | Try to abort active 'qmshutdown' tasks before stopping. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| timeout | integer | no | Wait maximal timeout seconds. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/status/suspend + +Suspend virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| statestorage | string | no | The storage for the VM state | +| todisk | boolean | no | If set, suspends the VM to disk. Will be resumed on next VM start. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/template + +Create a Template. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | no | If you want to convert only 1 disk to base image. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description": "You need 'VM.Allocate' permissions on /vms/{vmid}" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/termproxy + +Creates a TCP proxy connections. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| serial | string | no | opens a serial terminal (defaults to display) | + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "port": { + "type": "integer" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + }, + "user": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# PUT /nodes/{node}/qemu/{vmid}/unlink + +Unlink/delete disk images. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| idlist | string | yes | A list of disk IDs you want to delete. | +| force | boolean | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/qemu/{vmid}/vncproxy + +Creates a TCP VNC proxy connections. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| generate-password | boolean | no | Deprecated, do not use. Password is generated when required. | +| websocket | boolean | no | Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/qemu/{vmid}/vncwebsocket + +Opens a websocket for VNC traffic. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | Port number returned by previous vncproxy call. | +| vncticket | string | yes | Ticket from previous call to vncproxy. | + +## Returns + +```json +{ + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/query-oci-repo-tags + +List all tags for an OCI repository reference. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| reference | string | yes | The reference to the repository to query tags from. | + +## Returns + +```json +{ + "items": { + "type": "string" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/query-url-metadata + +Query metadata of an URL: file size, file name and mime type. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| url | string | yes | The URL to query the metadata from. | +| verify-certificates | boolean | no | If false, no SSL/TLS certificates will be verified. | + +## Returns + +```json +{ + "properties": { + "filename": { + "optional": 1, + "type": "string" + }, + "mimetype": { + "optional": 1, + "type": "string" + }, + "size": { + "optional": 1, + "renderer": "bytes", + "type": "integer" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/replication + +List status of all replication jobs on this node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| guest | integer | no | Only list replication jobs for this guest. | + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/replication/{id} + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/replication/{id}/log + +Read replication job log. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| start | integer | no | | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/replication/{id}/schedule_now + +Schedule replication job to start as soon as possible. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/replication/{id}/status + +Get replication job status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/report + +Gather various systems information about a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/rrd + +Read node RRD statistics (returns PNG) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/rrddata + +Read node RRD statistics + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan + +Index of available scan methods + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "method": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{method}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan/cifs + +Scan remote CIFS server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| server | string | yes | The server address (name or IP). | +| domain | string | no | SMB domain (Workgroup). | +| password | string | no | User password. | +| username | string | no | User name. | + +## Returns + +```json +{ + "items": { + "properties": { + "description": { + "description": "Descriptive text from server.", + "type": "string" + }, + "share": { + "description": "The cifs share name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan/iscsi + +Scan remote iSCSI server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| portal | string | yes | The iSCSI portal (IP or DNS name with optional port). | + +## Returns + +```json +{ + "items": { + "properties": { + "portal": { + "description": "The iSCSI portal name.", + "type": "string" + }, + "target": { + "description": "The iSCSI target name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan/lvm + +List local LVM volume groups. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "vg": { + "description": "The LVM logical volume group name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan/lvmthin + +List local LVM Thin Pools. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vg | string | yes | | + +## Returns + +```json +{ + "items": { + "properties": { + "lv": { + "description": "The LVM Thin Pool name (LVM logical volume).", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan/nfs + +Scan remote NFS server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| server | string | yes | The server address (name or IP). | + +## Returns + +```json +{ + "items": { + "properties": { + "options": { + "description": "NFS export options.", + "type": "string" + }, + "path": { + "description": "The exported path.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan/pbs + +Scan remote Proxmox Backup Server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | User password or API token secret. | +| server | string | yes | The server address (name or IP). | +| username | string | yes | User-name or API token-ID. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| port | integer | no | Optional port. | + +## Returns + +```json +{ + "items": { + "properties": { + "comment": { + "description": "Comment from server.", + "optional": 1, + "type": "string" + }, + "store": { + "description": "The datastore name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/scan/zfs + +Scan zfs pool list on local node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "pool": { + "description": "ZFS pool name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn + +SDN index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/fabrics/{fabric} + +Directory index for SDN fabric status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/fabrics/{fabric}/interfaces + +Get all interfaces for a fabric. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/fabrics/{fabric}/neighbors + +Get all neighbors for a fabric. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/fabrics/{fabric}/routes + +Get all routes for a fabric. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/vnets/{vnet} + +diridx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/vnets/{vnet}/mac-vrf + +Get the MAC VRF for a VNet in an EVPN zone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/zones + +Get status for all zones. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/zones/{zone} + +Directory index for SDN zone status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/zones/{zone}/bridges + +Get a list of all bridges (vnets) that are part of a zone, as well as the ports that are members of that bridge. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | zone name or "localnetwork" | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/zones/{zone}/content + +List zone content. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/sdn/zones/{zone}/ip-vrf + +Get the IP VRF of an EVPN zone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | Name of an EVPN zone. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/services + +Service list. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/services/{service} + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/services/{service}/reload + +Reload service. Falls back to restart if service cannot be reloaded. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/services/{service}/restart + +Hard restart service. Use reload if you want to reduce interruptions. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/services/{service}/start + +Start service. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/services/{service}/state + +Read service properties + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/services/{service}/stop + +Stop service. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/spiceshell + +Creates a SPICE shell. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cmd | string | no | Run specific command or default to login (requires 'root@pam') | +| cmd-opts | string | no | Add parameters to a command. Encoded as null terminated strings. | +| proxy | string | no | 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). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# POST /nodes/{node}/startall + +Start all VMs and containers located on this node (by default only those with onboot=1). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Issue start command even if virtual guest have 'onboot' not set or set to off. | +| max-workers | integer | no | 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. | +| vms | string | no | Only consider guests from this comma separated list of VMIDs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/status + +Read node status + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/status + +Reboot or shutdown a node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | string | yes | Specify the command. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/stopall + +Stop all VMs and Containers. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force-stop | boolean | no | Force a hard-stop after the timeout. | +| max-workers | integer | no | 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. | +| timeout | integer | no | Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced. | +| vms | string | no | Only consider Guests with these IDs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage + +Get status for all datastores. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | no | Only list stores which support this content type. | +| enabled | boolean | no | Only list stores which are enabled (not disabled in config). | +| format | boolean | no | Include information about formats | +| storage | string | no | Only list status for specified storage | +| target | string | no | If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage} + +diridx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/content + +List storage content. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | no | Only list content of this type. | +| vmid | integer | no | Only list images for this VM | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/storage/{storage}/content + +Allocate disk images. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| filename | string | yes | The name of the file to create. | +| size | string | yes | Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M) | +| vmid | integer | yes | Specify owner VM | +| format | string | no | Format of the image. | + +## Returns + +```json +{ + "description": "Volume identifier", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/storage/{storage}/content/{volume} + +Delete volume + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delay | integer | no | Time to wait for the task to finish. We return 'null' if the task finish within that time. | + +## Returns + +```json +{ + "optional": 1, + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/storage/{storage}/content/{volume} + +Get volume attributes + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/storage/{storage}/content/{volume} + +Copy a volume. This is experimental code - do not use. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Source volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target volume identifier | +| target_node | string | no | Target node. Default is local node. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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 /nodes/{node}/storage/{storage}/content/{volume} + +Update volume attributes + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| notes | string | no | The new notes. | +| protected | boolean | no | Protection status. Currently only supported for backups. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/storage/{storage}/download-url + +Download templates, ISO images, OVAs and VM images by using an URL. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | yes | Content type. | +| filename | string | yes | The name of the file to create. Caution: This will be normalized! | +| url | string | yes | The URL to download the file from. | +| checksum | string | no | The expected checksum of the file. | +| checksum-algorithm | string | no | The algorithm to calculate the checksum of the file. | +| compression | string | no | Decompress the downloaded file using the specified compression algorithm. | +| verify-certificates | boolean | no | If false, no SSL/TLS certificates will be verified. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/file-restore/download + +Extract a file or directory (as zip archive) from a PBS backup. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| filepath | string | yes | base64-path to the directory or file to download. | +| volume | string | yes | Backup volume ID or name. Currently only PBS snapshots are supported. | +| tar | boolean | no | Download dirs as 'tar.zst' instead of 'zip'. | + +## Returns + +```json +{ + "type": "any" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/file-restore/list + +List files and directories for single file restore under the given path. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| filepath | string | yes | base64-path to the directory or file being listed, or "/". | +| volume | string | yes | Backup volume ID or name. Currently only PBS snapshots are supported. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/identity + +Return identity information for this storage instance. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/import-metadata + +Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume | string | yes | Volume identifier for the guest archive/entry. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/storage/{storage}/oci-registry-pull + +Pull an OCI image from a registry. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| reference | string | yes | The reference to the OCI image to download. | +| filename | string | no | Custom destination file name of the OCI image. Caution: This will be normalized! | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/storage/{storage}/prunebackups + +Prune backups. Only those using the standard naming scheme are considered. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| type | string | no | Either 'qemu' or 'lxc'. Only consider backups for guests of this type. | +| vmid | integer | no | Only prune backups for this VM. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/storage/{storage}/prunebackups + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| type | string | no | Either 'qemu' or 'lxc'. Only consider backups for guests of this type. | +| vmid | integer | no | Only consider backups for this guest. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/rrd + +Read storage RRD statistics (returns PNG). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/rrddata + +Read storage RRD statistics. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/storage/{storage}/status + +Read storage status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/storage/{storage}/upload + +Upload templates, ISO images, OVAs and VM images. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | yes | Content type. | +| filename | string | yes | The name of the file to create. Caution: This will be normalized! | +| checksum | string | no | The expected checksum of the file. | +| checksum-algorithm | string | no | The algorithm to calculate the checksum of the file. | +| tmpfilename | string | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/subscription + +Delete subscription key of this node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/subscription + +Read subscription info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/subscription + +Update subscription info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Always connect to server, even if local cache is still valid. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/subscription + +Set subscription key. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| key | string | yes | Proxmox VE subscription key | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/suspendall + +Suspend all VMs. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max-workers | integer | no | Maximal number of parallel migration job. 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. | +| vms | string | no | Only consider Guests with these IDs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/syslog + +Read system log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| service | string | no | Service ID | +| since | string | no | Display all log since this date-time string. | +| start | integer | no | | +| until | string | no | Display all log until this date-time string. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/tasks + +Read task list for one node (finished tasks). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| errors | boolean | no | Only list tasks with a status of ERROR. | +| limit | integer | no | Only list this number of tasks. | +| since | integer | no | Only list tasks since this UNIX epoch. | +| source | string | no | List archived, active or all tasks. | +| start | integer | no | List tasks beginning from this offset. | +| statusfilter | string | no | List of Task States that should be returned. | +| typefilter | string | no | Only list tasks of this type (e.g., vzstart, vzdump). | +| until | integer | no | Only list tasks until this UNIX epoch. | +| userfilter | string | no | Only list tasks from this user. | +| vmid | integer | no | Only list tasks for this VM. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /nodes/{node}/tasks/{upid} + +Stop a task. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/tasks/{upid} + +upid_index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/tasks/{upid}/log + +Read task log. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | The task's unique ID. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| download | boolean | no | Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters | +| limit | integer | no | The number of lines to read from the tasklog. | +| start | integer | no | Start at this line when reading the tasklog | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/tasks/{upid}/status + +Read task status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | The task's unique ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/termproxy + +Creates a VNC Shell proxy. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cmd | string | no | Run specific command or default to login (requires 'root@pam') | +| cmd-opts | string | no | Add parameters to a command. Encoded as null terminated strings. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/time + +Read server time and time zone settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /nodes/{node}/time + +Set time zone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timezone | string | yes | Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/version + +API version details + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/vncshell + +Creates a VNC Shell proxy. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cmd | string | no | Run specific command or default to login (requires 'root@pam') | +| cmd-opts | string | no | Add parameters to a command. Encoded as null terminated strings. | +| height | integer | no | sets the height of the console in pixels. | +| websocket | boolean | no | use websocket instead of standard vnc. | +| width | integer | no | sets the width of the console in pixels. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` + + +--- + + + +# GET /nodes/{node}/vncwebsocket + +Opens a websocket for VNC traffic. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | Port number returned by previous 'vncshell' call. | +| vncticket | string | yes | Ticket from previous call to 'vncshell'. | + +## Returns + +```json +{ + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/vzdump + +Create backup. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | no | Only run if executed on this node. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| all | boolean | no | Backup all known guest systems on this host. | +| bwlimit | integer | no | Limit I/O bandwidth (in KiB/s). | +| compress | string | no | Compress dump file. | +| dumpdir | string | no | Store resulting files to specified directory. | +| exclude | string | no | Exclude specified guest systems (assumes --all) | +| exclude-path | array | no | Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory. | +| fleecing | string | no | Options for backup fleecing (VM only). | +| ionice | integer | no | 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. | +| job-id | string | no | 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. | +| lockwait | integer | no | Maximal time to wait for the global lock (minutes). | +| mailnotification | string | no | Deprecated: use notification targets/matchers instead. Specify when to send a notification mail | +| mailto | string | no | Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications. | +| mode | string | no | Backup mode. | +| notes-template | string | no | 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. | +| notification-mode | string | no | 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. | +| pbs-change-detection-mode | string | no | PBS mode used to detect file changes and switch encoding format for container backups. | +| performance | string | no | Other performance-related settings. | +| pigz | integer | no | Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count. | +| pool | string | no | Backup all known guest systems included in the specified pool. | +| protected | boolean | no | If true, mark backup(s) as protected. | +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| quiet | boolean | no | Be quiet. | +| remove | boolean | no | Prune older backups according to 'prune-backups'. | +| script | string | no | Use specified hook script. | +| stdexcludes | boolean | no | Exclude temporary files and logs. | +| stdout | boolean | no | Write tar to stdout, not to a file. | +| stop | boolean | no | Stop running backup jobs on this host. | +| stopwait | integer | no | Maximal time to wait until a guest system is stopped (minutes). | +| storage | string | no | Store resulting file to this storage. | +| tmpdir | string | no | Store temporary files to specified directory. | +| vmid | string | no | The ID of the guest system you want to backup. | +| zstd | integer | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/vzdump/defaults + +Get the currently configured vzdump defaults. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | no | The storage identifier. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /nodes/{node}/vzdump/extractconfig + +Extract configuration from vzdump backup archive. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume | string | yes | Volume identifier | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# POST /nodes/{node}/wakeonlan + +Try to wake a node via 'wake on LAN' network packet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | target node for wake on LAN packet | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "MAC address used to assemble the WoL magic packet.", + "format": "mac-addr", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /pools + +Delete pool. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You can only delete empty pools (no members)." +} +``` + +## Raw schema + +```json +{ + "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 /pools + +List pools or get pool configuration. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | no | | +| type | string | no | | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /pools + +Create new pool. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /pools + +Update pool. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | +| allow-move | boolean | no | Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one. | +| comment | string | no | | +| delete | boolean | no | Remove the passed VMIDs and/or storage IDs instead of adding them. | +| storage | string | no | List of storage IDs to add or remove from this pool. | +| vms | string | no | List of guest VMIDs to add or remove from this pool. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You also need the right to modify permissions on any object you add/delete." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /pools/{poolid} + +Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}'). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You can only delete empty pools (no members)." +} +``` + +## Raw schema + +```json +{ + "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 /pools/{poolid} + +Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}'). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /pools/{poolid} + +Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| allow-move | boolean | no | Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one. | +| comment | string | no | | +| delete | boolean | no | Remove the passed VMIDs and/or storage IDs instead of adding them. | +| storage | string | no | List of storage IDs to add or remove from this pool. | +| vms | string | no | List of guest VMIDs to add or remove from this pool. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You also need the right to modify permissions on any object you add/delete." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /storage + +Storage index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list storage of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "storage": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{storage}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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 /storage + +Create a new storage. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | +| type | string | yes | Storage type. | +| authsupported | string | no | Authsupported. | +| base | string | no | Base volume. This volume is automatically activated. | +| blocksize | string | no | ZFS block size | +| bwlimit | string | no | Set I/O bandwidth limit for various operations (in KiB/s). | +| comstar_hg | string | no | host group for comstar views | +| comstar_tg | string | no | target group for comstar views | +| content | string | no | Allowed content types. NOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs. | +| content-dirs | string | no | Overrides for default content type directories. | +| create-base-path | boolean | no | Create the base directory if it doesn't exist. | +| create-subdirs | boolean | no | Populate the directory with the default structure. | +| data-pool | string | no | Data Pool (for erasure coding only) | +| datastore | string | no | Proxmox Backup Server datastore name. | +| disable | boolean | no | Flag to disable the storage. | +| domain | string | no | CIFS domain. | +| encryption-key | string | no | Encryption key. Use 'autogen' to generate one automatically without passphrase. | +| export | string | no | NFS export path. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| format | string | no | Default image format. | +| fs-name | string | no | The Ceph filesystem name. | +| fuse | boolean | no | Mount CephFS through FUSE. | +| is_mountpoint | string | no | 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. | +| iscsiprovider | string | no | iscsi provider | +| keyring | string | no | Client keyring contents (for external clusters). | +| krbd | boolean | no | Always access rbd through krbd kernel module. | +| lio_tpg | string | no | target portal group for Linux LIO targets | +| master-pubkey | string | no | Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup. | +| max-protected-backups | integer | no | Maximal number of protected backups per guest. Use '-1' for unlimited. | +| mkdir | boolean | no | 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. | +| monhost | string | no | IP addresses of monitors (for external clusters). | +| mountpoint | string | no | mount point | +| namespace | string | no | Namespace. | +| nocow | boolean | no | 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. | +| nodes | string | no | List of nodes for which the storage configuration applies. | +| nowritecache | boolean | no | disable write caching on the target | +| options | string | no | NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs') | +| password | string | no | Password for accessing the share/datastore. | +| path | string | no | File system path. | +| pool | string | no | Pool. | +| port | integer | no | 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. | +| portal | string | no | iSCSI portal (IP or DNS name with optional port). | +| preallocation | string | no | Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. | +| prune-backups | string | no | 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. | +| saferemove | boolean | no | Zero-out data when removing LVs. | +| saferemove_throughput | string | no | Wipe throughput (cstream -t parameter value). | +| saferemove-stepsize | integer | no | Wipe step size in MiB. It will be capped to the maximum supported by the storage. | +| server | string | no | Server IP or DNS name. | +| share | string | no | CIFS share. | +| shared | boolean | no | 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! | +| skip-cert-verification | boolean | no | Disable TLS certificate verification, only enable on fully trusted networks! | +| smbversion | string | no | SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. | +| snapshot-as-volume-chain | boolean | no | Enable support for creating storage-vendor agnostic snapshot through volume backing-chains. | +| sparse | boolean | no | use sparse volumes | +| subdir | string | no | Subdir to mount. | +| tagged_only | boolean | no | Only list logical volumes tagged with 'pve-vm-ID'. | +| target | string | no | iSCSI target. | +| thinpool | string | no | LVM thin pool LV name. | +| username | string | no | RBD Id. | +| vgname | string | no | Volume group name. | +| zfs-base-path | string | no | Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# DELETE /storage/{storage} + +Delete storage configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /storage/{storage} + +Read storage configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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 /storage/{storage} + +Update storage configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| blocksize | string | no | ZFS block size | +| bwlimit | string | no | Set I/O bandwidth limit for various operations (in KiB/s). | +| comstar_hg | string | no | host group for comstar views | +| comstar_tg | string | no | target group for comstar views | +| content | string | no | Allowed content types. NOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs. | +| content-dirs | string | no | Overrides for default content type directories. | +| create-base-path | boolean | no | Create the base directory if it doesn't exist. | +| create-subdirs | boolean | no | Populate the directory with the default structure. | +| data-pool | string | no | Data Pool (for erasure coding only) | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable the storage. | +| domain | string | no | CIFS domain. | +| encryption-key | string | no | Encryption key. Use 'autogen' to generate one automatically without passphrase. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| format | string | no | Default image format. | +| fs-name | string | no | The Ceph filesystem name. | +| fuse | boolean | no | Mount CephFS through FUSE. | +| is_mountpoint | string | no | 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. | +| keyring | string | no | Client keyring contents (for external clusters). | +| krbd | boolean | no | Always access rbd through krbd kernel module. | +| lio_tpg | string | no | target portal group for Linux LIO targets | +| master-pubkey | string | no | Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup. | +| max-protected-backups | integer | no | Maximal number of protected backups per guest. Use '-1' for unlimited. | +| mkdir | boolean | no | 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. | +| monhost | string | no | IP addresses of monitors (for external clusters). | +| mountpoint | string | no | mount point | +| namespace | string | no | Namespace. | +| nocow | boolean | no | 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. | +| nodes | string | no | List of nodes for which the storage configuration applies. | +| nowritecache | boolean | no | disable write caching on the target | +| options | string | no | NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs') | +| password | string | no | Password for accessing the share/datastore. | +| pool | string | no | Pool. | +| port | integer | no | 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. | +| preallocation | string | no | Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. | +| prune-backups | string | no | 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. | +| saferemove | boolean | no | Zero-out data when removing LVs. | +| saferemove_throughput | string | no | Wipe throughput (cstream -t parameter value). | +| saferemove-stepsize | integer | no | Wipe step size in MiB. It will be capped to the maximum supported by the storage. | +| server | string | no | Server IP or DNS name. | +| shared | boolean | no | 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! | +| skip-cert-verification | boolean | no | Disable TLS certificate verification, only enable on fully trusted networks! | +| smbversion | string | no | SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. | +| snapshot-as-volume-chain | boolean | no | Enable support for creating storage-vendor agnostic snapshot through volume backing-chains. | +| sparse | boolean | no | use sparse volumes | +| subdir | string | no | Subdir to mount. | +| tagged_only | boolean | no | Only list logical volumes tagged with 'pve-vm-ID'. | +| username | string | no | RBD Id. | +| zfs-base-path | string | no | Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + + +--- + + + +# GET /version + +API version details, including some parts of the global datacenter config. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` + diff --git a/docs/pve-api/llms.txt b/docs/pve-api/llms.txt new file mode 100644 index 00000000000..45d384ace3a --- /dev/null +++ b/docs/pve-api/llms.txt @@ -0,0 +1,99 @@ +# Proxmox VE API Docs + +Static AI-readable documentation generated from local Proxmox VE apidoc.js. This is documentation only; it does not call the API. + +## Sections +- /access: 45 endpoints +- /cluster: 259 endpoints +- /nodes: 358 endpoints +- /pools: 7 endpoints +- /storage: 5 endpoints +- /version: 1 endpoints + +## Common endpoints +- GET /cluster/qemu: index +- GET /cluster/qemu/cpu-flags: index +- GET /cluster/qemu/custom-cpu-models: config +- POST /cluster/qemu/custom-cpu-models: create +- DELETE /cluster/qemu/custom-cpu-models/{cputype}: delete +- GET /cluster/qemu/custom-cpu-models/{cputype}: info +- PUT /cluster/qemu/custom-cpu-models/{cputype}: update +- GET /nodes: index +- GET /nodes/{node}/capabilities/qemu: qemu_caps_index +- GET /nodes/{node}/capabilities/qemu/cpu: index +- GET /nodes/{node}/capabilities/qemu/cpu-flags: index +- GET /nodes/{node}/capabilities/qemu/machines: types +- GET /nodes/{node}/capabilities/qemu/migration: capabilities +- GET /nodes/{node}/lxc: vmlist +- POST /nodes/{node}/lxc: create_vm +- DELETE /nodes/{node}/lxc/{vmid}: destroy_vm +- GET /nodes/{node}/lxc/{vmid}: vmdiridx +- POST /nodes/{node}/lxc/{vmid}/clone: clone_vm +- GET /nodes/{node}/lxc/{vmid}/config: vm_config +- PUT /nodes/{node}/lxc/{vmid}/config: update_vm +- GET /nodes/{node}/lxc/{vmid}/feature: vm_feature +- GET /nodes/{node}/lxc/{vmid}/firewall: index +- GET /nodes/{node}/lxc/{vmid}/firewall/aliases: get_aliases +- POST /nodes/{node}/lxc/{vmid}/firewall/aliases: create_alias +- DELETE /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}: remove_alias +- GET /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}: read_alias +- PUT /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}: update_alias +- GET /nodes/{node}/lxc/{vmid}/firewall/ipset: ipset_index +- POST /nodes/{node}/lxc/{vmid}/firewall/ipset: create_ipset +- DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}: delete_ipset +- GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}: get_ipset +- POST /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}: create_ip +- DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}: remove_ip +- GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}: read_ip +- PUT /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}: update_ip +- GET /nodes/{node}/lxc/{vmid}/firewall/log: log +- GET /nodes/{node}/lxc/{vmid}/firewall/options: get_options +- PUT /nodes/{node}/lxc/{vmid}/firewall/options: set_options +- GET /nodes/{node}/lxc/{vmid}/firewall/refs: refs +- GET /nodes/{node}/lxc/{vmid}/firewall/rules: get_rules +- POST /nodes/{node}/lxc/{vmid}/firewall/rules: create_rule +- DELETE /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}: delete_rule +- GET /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}: get_rule +- PUT /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}: update_rule +- GET /nodes/{node}/lxc/{vmid}/interfaces: ip +- GET /nodes/{node}/lxc/{vmid}/migrate: migrate_vm_precondition +- POST /nodes/{node}/lxc/{vmid}/migrate: migrate_vm +- POST /nodes/{node}/lxc/{vmid}/move_volume: move_volume +- POST /nodes/{node}/lxc/{vmid}/mtunnel: mtunnel +- GET /nodes/{node}/lxc/{vmid}/mtunnelwebsocket: mtunnelwebsocket +- GET /nodes/{node}/lxc/{vmid}/pending: vm_pending +- POST /nodes/{node}/lxc/{vmid}/remote_migrate: remote_migrate_vm +- PUT /nodes/{node}/lxc/{vmid}/resize: resize_vm +- GET /nodes/{node}/lxc/{vmid}/rrd: rrd +- GET /nodes/{node}/lxc/{vmid}/rrddata: rrddata +- GET /nodes/{node}/lxc/{vmid}/snapshot: list +- POST /nodes/{node}/lxc/{vmid}/snapshot: snapshot +- DELETE /nodes/{node}/lxc/{vmid}/snapshot/{snapname}: delsnapshot +- GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}: snapshot_cmd_idx +- GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config: get_snapshot_config +- PUT /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config: update_snapshot_config +- POST /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback: rollback +- POST /nodes/{node}/lxc/{vmid}/spiceproxy: spiceproxy +- GET /nodes/{node}/lxc/{vmid}/status: vmcmdidx +- GET /nodes/{node}/lxc/{vmid}/status/current: vm_status +- POST /nodes/{node}/lxc/{vmid}/status/reboot: vm_reboot +- POST /nodes/{node}/lxc/{vmid}/status/resume: vm_resume +- POST /nodes/{node}/lxc/{vmid}/status/shutdown: vm_shutdown +- POST /nodes/{node}/lxc/{vmid}/status/start: vm_start +- POST /nodes/{node}/lxc/{vmid}/status/stop: vm_stop +- POST /nodes/{node}/lxc/{vmid}/status/suspend: vm_suspend +- POST /nodes/{node}/lxc/{vmid}/template: template +- POST /nodes/{node}/lxc/{vmid}/termproxy: termproxy +- POST /nodes/{node}/lxc/{vmid}/vncproxy: vncproxy +- GET /nodes/{node}/lxc/{vmid}/vncwebsocket: vncwebsocket +- GET /nodes/{node}/qemu: vmlist +- POST /nodes/{node}/qemu: create_vm +- DELETE /nodes/{node}/qemu/{vmid}: destroy_vm +- GET /nodes/{node}/qemu/{vmid}: vmdiridx +- GET /nodes/{node}/qemu/{vmid}/agent: index + +## Files +- endpoints.json: normalized endpoint records +- endpoints.ndjson: one normalized endpoint per line +- search-index.json: compact search records with semantic aliases +- markdown/: per-section and per-endpoint Markdown files diff --git a/docs/pve-api/markdown/access.md b/docs/pve-api/markdown/access.md new file mode 100644 index 00000000000..b8f1902a91a --- /dev/null +++ b/docs/pve-api/markdown/access.md @@ -0,0 +1,51 @@ +# /access + +Endpoints in the `/access` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/access` | [index](endpoints/GET_access.md) | +| GET | `/access/acl` | [read_acl](endpoints/GET_access_acl.md) | +| PUT | `/access/acl` | [update_acl](endpoints/PUT_access_acl.md) | +| GET | `/access/domains` | [index](endpoints/GET_access_domains.md) | +| POST | `/access/domains` | [create](endpoints/POST_access_domains.md) | +| DELETE | `/access/domains/{realm}` | [delete](endpoints/DELETE_access_domains_realm.md) | +| GET | `/access/domains/{realm}` | [read](endpoints/GET_access_domains_realm.md) | +| PUT | `/access/domains/{realm}` | [update](endpoints/PUT_access_domains_realm.md) | +| POST | `/access/domains/{realm}/sync` | [sync](endpoints/POST_access_domains_realm_sync.md) | +| GET | `/access/groups` | [index](endpoints/GET_access_groups.md) | +| POST | `/access/groups` | [create_group](endpoints/POST_access_groups.md) | +| DELETE | `/access/groups/{groupid}` | [delete_group](endpoints/DELETE_access_groups_groupid.md) | +| GET | `/access/groups/{groupid}` | [read_group](endpoints/GET_access_groups_groupid.md) | +| PUT | `/access/groups/{groupid}` | [update_group](endpoints/PUT_access_groups_groupid.md) | +| GET | `/access/openid` | [index](endpoints/GET_access_openid.md) | +| POST | `/access/openid/auth-url` | [auth_url](endpoints/POST_access_openid_auth_url.md) | +| POST | `/access/openid/login` | [login](endpoints/POST_access_openid_login.md) | +| PUT | `/access/password` | [change_password](endpoints/PUT_access_password.md) | +| GET | `/access/permissions` | [permissions](endpoints/GET_access_permissions.md) | +| GET | `/access/roles` | [index](endpoints/GET_access_roles.md) | +| POST | `/access/roles` | [create_role](endpoints/POST_access_roles.md) | +| DELETE | `/access/roles/{roleid}` | [delete_role](endpoints/DELETE_access_roles_roleid.md) | +| GET | `/access/roles/{roleid}` | [read_role](endpoints/GET_access_roles_roleid.md) | +| PUT | `/access/roles/{roleid}` | [update_role](endpoints/PUT_access_roles_roleid.md) | +| GET | `/access/tfa` | [list_tfa](endpoints/GET_access_tfa.md) | +| GET | `/access/tfa/{userid}` | [list_user_tfa](endpoints/GET_access_tfa_userid.md) | +| POST | `/access/tfa/{userid}` | [add_tfa_entry](endpoints/POST_access_tfa_userid.md) | +| DELETE | `/access/tfa/{userid}/{id}` | [delete_tfa](endpoints/DELETE_access_tfa_userid_id.md) | +| GET | `/access/tfa/{userid}/{id}` | [get_tfa_entry](endpoints/GET_access_tfa_userid_id.md) | +| PUT | `/access/tfa/{userid}/{id}` | [update_tfa_entry](endpoints/PUT_access_tfa_userid_id.md) | +| GET | `/access/ticket` | [get_ticket](endpoints/GET_access_ticket.md) | +| POST | `/access/ticket` | [create_ticket](endpoints/POST_access_ticket.md) | +| GET | `/access/users` | [index](endpoints/GET_access_users.md) | +| POST | `/access/users` | [create_user](endpoints/POST_access_users.md) | +| DELETE | `/access/users/{userid}` | [delete_user](endpoints/DELETE_access_users_userid.md) | +| GET | `/access/users/{userid}` | [read_user](endpoints/GET_access_users_userid.md) | +| PUT | `/access/users/{userid}` | [update_user](endpoints/PUT_access_users_userid.md) | +| GET | `/access/users/{userid}/tfa` | [read_user_tfa_type](endpoints/GET_access_users_userid_tfa.md) | +| GET | `/access/users/{userid}/token` | [token_index](endpoints/GET_access_users_userid_token.md) | +| DELETE | `/access/users/{userid}/token/{tokenid}` | [remove_token](endpoints/DELETE_access_users_userid_token_tokenid.md) | +| GET | `/access/users/{userid}/token/{tokenid}` | [read_token](endpoints/GET_access_users_userid_token_tokenid.md) | +| POST | `/access/users/{userid}/token/{tokenid}` | [generate_token](endpoints/POST_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/token/{tokenid}` | [update_token_info](endpoints/PUT_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/unlock-tfa` | [unlock_tfa](endpoints/PUT_access_users_userid_unlock_tfa.md) | +| POST | `/access/vncticket` | [verify_vnc_ticket](endpoints/POST_access_vncticket.md) | diff --git a/docs/pve-api/markdown/cluster.md b/docs/pve-api/markdown/cluster.md new file mode 100644 index 00000000000..cd7e7a3ee6c --- /dev/null +++ b/docs/pve-api/markdown/cluster.md @@ -0,0 +1,265 @@ +# /cluster + +Endpoints in the `/cluster` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/cluster` | [index](endpoints/GET_cluster.md) | +| GET | `/cluster/acme` | [index](endpoints/GET_cluster_acme.md) | +| GET | `/cluster/acme/account` | [account_index](endpoints/GET_cluster_acme_account.md) | +| POST | `/cluster/acme/account` | [register_account](endpoints/POST_cluster_acme_account.md) | +| DELETE | `/cluster/acme/account/{name}` | [deactivate_account](endpoints/DELETE_cluster_acme_account_name.md) | +| GET | `/cluster/acme/account/{name}` | [get_account](endpoints/GET_cluster_acme_account_name.md) | +| PUT | `/cluster/acme/account/{name}` | [update_account](endpoints/PUT_cluster_acme_account_name.md) | +| GET | `/cluster/acme/challenge-schema` | [challengeschema](endpoints/GET_cluster_acme_challenge_schema.md) | +| GET | `/cluster/acme/directories` | [get_directories](endpoints/GET_cluster_acme_directories.md) | +| GET | `/cluster/acme/meta` | [get_meta](endpoints/GET_cluster_acme_meta.md) | +| GET | `/cluster/acme/plugins` | [index](endpoints/GET_cluster_acme_plugins.md) | +| POST | `/cluster/acme/plugins` | [add_plugin](endpoints/POST_cluster_acme_plugins.md) | +| DELETE | `/cluster/acme/plugins/{id}` | [delete_plugin](endpoints/DELETE_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/plugins/{id}` | [get_plugin_config](endpoints/GET_cluster_acme_plugins_id.md) | +| PUT | `/cluster/acme/plugins/{id}` | [update_plugin](endpoints/PUT_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/tos` | [get_tos](endpoints/GET_cluster_acme_tos.md) | +| GET | `/cluster/backup` | [index](endpoints/GET_cluster_backup.md) | +| POST | `/cluster/backup` | [create_job](endpoints/POST_cluster_backup.md) | +| GET | `/cluster/backup-info` | [index](endpoints/GET_cluster_backup_info.md) | +| GET | `/cluster/backup-info/not-backed-up` | [get_guests_not_in_backup](endpoints/GET_cluster_backup_info_not_backed_up.md) | +| DELETE | `/cluster/backup/{id}` | [delete_job](endpoints/DELETE_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}` | [read_job](endpoints/GET_cluster_backup_id.md) | +| PUT | `/cluster/backup/{id}` | [update_job](endpoints/PUT_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}/included_volumes` | [get_volume_backup_included](endpoints/GET_cluster_backup_id_included_volumes.md) | +| GET | `/cluster/bulk-action` | [index](endpoints/GET_cluster_bulk_action.md) | +| GET | `/cluster/bulk-action/guest` | [index](endpoints/GET_cluster_bulk_action_guest.md) | +| POST | `/cluster/bulk-action/guest/migrate` | [migrate](endpoints/POST_cluster_bulk_action_guest_migrate.md) | +| POST | `/cluster/bulk-action/guest/shutdown` | [shutdown](endpoints/POST_cluster_bulk_action_guest_shutdown.md) | +| POST | `/cluster/bulk-action/guest/start` | [start](endpoints/POST_cluster_bulk_action_guest_start.md) | +| POST | `/cluster/bulk-action/guest/suspend` | [suspend](endpoints/POST_cluster_bulk_action_guest_suspend.md) | +| GET | `/cluster/ceph` | [cephindex](endpoints/GET_cluster_ceph.md) | +| GET | `/cluster/ceph/flags` | [get_all_flags](endpoints/GET_cluster_ceph_flags.md) | +| PUT | `/cluster/ceph/flags` | [set_flags](endpoints/PUT_cluster_ceph_flags.md) | +| GET | `/cluster/ceph/flags/{flag}` | [get_flag](endpoints/GET_cluster_ceph_flags_flag.md) | +| PUT | `/cluster/ceph/flags/{flag}` | [update_flag](endpoints/PUT_cluster_ceph_flags_flag.md) | +| GET | `/cluster/ceph/metadata` | [metadata](endpoints/GET_cluster_ceph_metadata.md) | +| GET | `/cluster/ceph/status` | [status](endpoints/GET_cluster_ceph_status.md) | +| GET | `/cluster/config` | [index](endpoints/GET_cluster_config.md) | +| POST | `/cluster/config` | [create](endpoints/POST_cluster_config.md) | +| GET | `/cluster/config/apiversion` | [join_api_version](endpoints/GET_cluster_config_apiversion.md) | +| GET | `/cluster/config/join` | [join_info](endpoints/GET_cluster_config_join.md) | +| POST | `/cluster/config/join` | [join](endpoints/POST_cluster_config_join.md) | +| GET | `/cluster/config/nodes` | [nodes](endpoints/GET_cluster_config_nodes.md) | +| DELETE | `/cluster/config/nodes/{node}` | [delnode](endpoints/DELETE_cluster_config_nodes_node.md) | +| POST | `/cluster/config/nodes/{node}` | [addnode](endpoints/POST_cluster_config_nodes_node.md) | +| GET | `/cluster/config/qdevice` | [status](endpoints/GET_cluster_config_qdevice.md) | +| GET | `/cluster/config/totem` | [totem](endpoints/GET_cluster_config_totem.md) | +| GET | `/cluster/firewall` | [index](endpoints/GET_cluster_firewall.md) | +| GET | `/cluster/firewall/aliases` | [get_aliases](endpoints/GET_cluster_firewall_aliases.md) | +| POST | `/cluster/firewall/aliases` | [create_alias](endpoints/POST_cluster_firewall_aliases.md) | +| DELETE | `/cluster/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/aliases/{name}` | [read_alias](endpoints/GET_cluster_firewall_aliases_name.md) | +| PUT | `/cluster/firewall/aliases/{name}` | [update_alias](endpoints/PUT_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/groups` | [list_security_groups](endpoints/GET_cluster_firewall_groups.md) | +| POST | `/cluster/firewall/groups` | [create_security_group](endpoints/POST_cluster_firewall_groups.md) | +| DELETE | `/cluster/firewall/groups/{group}` | [delete_security_group](endpoints/DELETE_cluster_firewall_groups_group.md) | +| GET | `/cluster/firewall/groups/{group}` | [get_rules](endpoints/GET_cluster_firewall_groups_group.md) | +| POST | `/cluster/firewall/groups/{group}` | [create_rule](endpoints/POST_cluster_firewall_groups_group.md) | +| DELETE | `/cluster/firewall/groups/{group}/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/groups/{group}/{pos}` | [get_rule](endpoints/GET_cluster_firewall_groups_group_pos.md) | +| PUT | `/cluster/firewall/groups/{group}/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/ipset` | [ipset_index](endpoints/GET_cluster_firewall_ipset.md) | +| POST | `/cluster/firewall/ipset` | [create_ipset](endpoints/POST_cluster_firewall_ipset.md) | +| DELETE | `/cluster/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_cluster_firewall_ipset_name.md) | +| GET | `/cluster/firewall/ipset/{name}` | [get_ipset](endpoints/GET_cluster_firewall_ipset_name.md) | +| POST | `/cluster/firewall/ipset/{name}` | [create_ip](endpoints/POST_cluster_firewall_ipset_name.md) | +| DELETE | `/cluster/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_cluster_firewall_ipset_name_cidr.md) | +| PUT | `/cluster/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/macros` | [get_macros](endpoints/GET_cluster_firewall_macros.md) | +| GET | `/cluster/firewall/options` | [get_options](endpoints/GET_cluster_firewall_options.md) | +| PUT | `/cluster/firewall/options` | [set_options](endpoints/PUT_cluster_firewall_options.md) | +| GET | `/cluster/firewall/refs` | [refs](endpoints/GET_cluster_firewall_refs.md) | +| GET | `/cluster/firewall/rules` | [get_rules](endpoints/GET_cluster_firewall_rules.md) | +| POST | `/cluster/firewall/rules` | [create_rule](endpoints/POST_cluster_firewall_rules.md) | +| DELETE | `/cluster/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_rules_pos.md) | +| GET | `/cluster/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_firewall_rules_pos.md) | +| PUT | `/cluster/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_rules_pos.md) | +| GET | `/cluster/ha` | [index](endpoints/GET_cluster_ha.md) | +| GET | `/cluster/ha/groups` | [index](endpoints/GET_cluster_ha_groups.md) | +| POST | `/cluster/ha/groups` | [create](endpoints/POST_cluster_ha_groups.md) | +| DELETE | `/cluster/ha/groups/{group}` | [delete](endpoints/DELETE_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/groups/{group}` | [read](endpoints/GET_cluster_ha_groups_group.md) | +| PUT | `/cluster/ha/groups/{group}` | [update](endpoints/PUT_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/resources` | [index](endpoints/GET_cluster_ha_resources.md) | +| POST | `/cluster/ha/resources` | [create](endpoints/POST_cluster_ha_resources.md) | +| DELETE | `/cluster/ha/resources/{sid}` | [delete](endpoints/DELETE_cluster_ha_resources_sid.md) | +| GET | `/cluster/ha/resources/{sid}` | [read](endpoints/GET_cluster_ha_resources_sid.md) | +| PUT | `/cluster/ha/resources/{sid}` | [update](endpoints/PUT_cluster_ha_resources_sid.md) | +| POST | `/cluster/ha/resources/{sid}/migrate` | [migrate](endpoints/POST_cluster_ha_resources_sid_migrate.md) | +| POST | `/cluster/ha/resources/{sid}/relocate` | [relocate](endpoints/POST_cluster_ha_resources_sid_relocate.md) | +| GET | `/cluster/ha/rules` | [index](endpoints/GET_cluster_ha_rules.md) | +| POST | `/cluster/ha/rules` | [create_rule](endpoints/POST_cluster_ha_rules.md) | +| DELETE | `/cluster/ha/rules/{rule}` | [delete_rule](endpoints/DELETE_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/rules/{rule}` | [read_rule](endpoints/GET_cluster_ha_rules_rule.md) | +| PUT | `/cluster/ha/rules/{rule}` | [update_rule](endpoints/PUT_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/status` | [index](endpoints/GET_cluster_ha_status.md) | +| POST | `/cluster/ha/status/arm-ha` | [arm-ha](endpoints/POST_cluster_ha_status_arm_ha.md) | +| GET | `/cluster/ha/status/current` | [status](endpoints/GET_cluster_ha_status_current.md) | +| POST | `/cluster/ha/status/disarm-ha` | [disarm-ha](endpoints/POST_cluster_ha_status_disarm_ha.md) | +| GET | `/cluster/ha/status/manager_status` | [manager_status](endpoints/GET_cluster_ha_status_manager_status.md) | +| GET | `/cluster/jobs` | [index](endpoints/GET_cluster_jobs.md) | +| GET | `/cluster/jobs/realm-sync` | [syncjob_index](endpoints/GET_cluster_jobs_realm_sync.md) | +| DELETE | `/cluster/jobs/realm-sync/{id}` | [delete_job](endpoints/DELETE_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/realm-sync/{id}` | [read_job](endpoints/GET_cluster_jobs_realm_sync_id.md) | +| POST | `/cluster/jobs/realm-sync/{id}` | [create_job](endpoints/POST_cluster_jobs_realm_sync_id.md) | +| PUT | `/cluster/jobs/realm-sync/{id}` | [update_job](endpoints/PUT_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/schedule-analyze` | [schedule-analyze](endpoints/GET_cluster_jobs_schedule_analyze.md) | +| GET | `/cluster/log` | [log](endpoints/GET_cluster_log.md) | +| GET | `/cluster/mapping` | [index](endpoints/GET_cluster_mapping.md) | +| GET | `/cluster/mapping/dir` | [index](endpoints/GET_cluster_mapping_dir.md) | +| POST | `/cluster/mapping/dir` | [create](endpoints/POST_cluster_mapping_dir.md) | +| DELETE | `/cluster/mapping/dir/{id}` | [delete](endpoints/DELETE_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/dir/{id}` | [get](endpoints/GET_cluster_mapping_dir_id.md) | +| PUT | `/cluster/mapping/dir/{id}` | [update](endpoints/PUT_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/pci` | [index](endpoints/GET_cluster_mapping_pci.md) | +| POST | `/cluster/mapping/pci` | [create](endpoints/POST_cluster_mapping_pci.md) | +| DELETE | `/cluster/mapping/pci/{id}` | [delete](endpoints/DELETE_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/pci/{id}` | [get](endpoints/GET_cluster_mapping_pci_id.md) | +| PUT | `/cluster/mapping/pci/{id}` | [update](endpoints/PUT_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/usb` | [index](endpoints/GET_cluster_mapping_usb.md) | +| POST | `/cluster/mapping/usb` | [create](endpoints/POST_cluster_mapping_usb.md) | +| DELETE | `/cluster/mapping/usb/{id}` | [delete](endpoints/DELETE_cluster_mapping_usb_id.md) | +| GET | `/cluster/mapping/usb/{id}` | [get](endpoints/GET_cluster_mapping_usb_id.md) | +| PUT | `/cluster/mapping/usb/{id}` | [update](endpoints/PUT_cluster_mapping_usb_id.md) | +| GET | `/cluster/metrics` | [index](endpoints/GET_cluster_metrics.md) | +| GET | `/cluster/metrics/export` | [export](endpoints/GET_cluster_metrics_export.md) | +| GET | `/cluster/metrics/server` | [server_index](endpoints/GET_cluster_metrics_server.md) | +| DELETE | `/cluster/metrics/server/{id}` | [delete](endpoints/DELETE_cluster_metrics_server_id.md) | +| GET | `/cluster/metrics/server/{id}` | [read](endpoints/GET_cluster_metrics_server_id.md) | +| POST | `/cluster/metrics/server/{id}` | [create](endpoints/POST_cluster_metrics_server_id.md) | +| PUT | `/cluster/metrics/server/{id}` | [update](endpoints/PUT_cluster_metrics_server_id.md) | +| GET | `/cluster/nextid` | [nextid](endpoints/GET_cluster_nextid.md) | +| GET | `/cluster/notifications` | [index](endpoints/GET_cluster_notifications.md) | +| GET | `/cluster/notifications/endpoints` | [endpoints_index](endpoints/GET_cluster_notifications_endpoints.md) | +| GET | `/cluster/notifications/endpoints/gotify` | [get_gotify_endpoints](endpoints/GET_cluster_notifications_endpoints_gotify.md) | +| POST | `/cluster/notifications/endpoints/gotify` | [create_gotify_endpoint](endpoints/POST_cluster_notifications_endpoints_gotify.md) | +| DELETE | `/cluster/notifications/endpoints/gotify/{name}` | [delete_gotify_endpoint](endpoints/DELETE_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/gotify/{name}` | [get_gotify_endpoint](endpoints/GET_cluster_notifications_endpoints_gotify_name.md) | +| PUT | `/cluster/notifications/endpoints/gotify/{name}` | [update_gotify_endpoint](endpoints/PUT_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail` | [get_sendmail_endpoints](endpoints/GET_cluster_notifications_endpoints_sendmail.md) | +| POST | `/cluster/notifications/endpoints/sendmail` | [create_sendmail_endpoint](endpoints/POST_cluster_notifications_endpoints_sendmail.md) | +| DELETE | `/cluster/notifications/endpoints/sendmail/{name}` | [delete_sendmail_endpoint](endpoints/DELETE_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail/{name}` | [get_sendmail_endpoint](endpoints/GET_cluster_notifications_endpoints_sendmail_name.md) | +| PUT | `/cluster/notifications/endpoints/sendmail/{name}` | [update_sendmail_endpoint](endpoints/PUT_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/smtp` | [get_smtp_endpoints](endpoints/GET_cluster_notifications_endpoints_smtp.md) | +| POST | `/cluster/notifications/endpoints/smtp` | [create_smtp_endpoint](endpoints/POST_cluster_notifications_endpoints_smtp.md) | +| DELETE | `/cluster/notifications/endpoints/smtp/{name}` | [delete_smtp_endpoint](endpoints/DELETE_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/smtp/{name}` | [get_smtp_endpoint](endpoints/GET_cluster_notifications_endpoints_smtp_name.md) | +| PUT | `/cluster/notifications/endpoints/smtp/{name}` | [update_smtp_endpoint](endpoints/PUT_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/webhook` | [get_webhook_endpoints](endpoints/GET_cluster_notifications_endpoints_webhook.md) | +| POST | `/cluster/notifications/endpoints/webhook` | [create_webhook_endpoint](endpoints/POST_cluster_notifications_endpoints_webhook.md) | +| DELETE | `/cluster/notifications/endpoints/webhook/{name}` | [delete_webhook_endpoint](endpoints/DELETE_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/endpoints/webhook/{name}` | [get_webhook_endpoint](endpoints/GET_cluster_notifications_endpoints_webhook_name.md) | +| PUT | `/cluster/notifications/endpoints/webhook/{name}` | [update_webhook_endpoint](endpoints/PUT_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/matcher-field-values` | [get_matcher_field_values](endpoints/GET_cluster_notifications_matcher_field_values.md) | +| GET | `/cluster/notifications/matcher-fields` | [get_matcher_fields](endpoints/GET_cluster_notifications_matcher_fields.md) | +| GET | `/cluster/notifications/matchers` | [get_matchers](endpoints/GET_cluster_notifications_matchers.md) | +| POST | `/cluster/notifications/matchers` | [create_matcher](endpoints/POST_cluster_notifications_matchers.md) | +| DELETE | `/cluster/notifications/matchers/{name}` | [delete_matcher](endpoints/DELETE_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/matchers/{name}` | [get_matcher](endpoints/GET_cluster_notifications_matchers_name.md) | +| PUT | `/cluster/notifications/matchers/{name}` | [update_matcher](endpoints/PUT_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/targets` | [get_all_targets](endpoints/GET_cluster_notifications_targets.md) | +| POST | `/cluster/notifications/targets/{name}/test` | [test_target](endpoints/POST_cluster_notifications_targets_name_test.md) | +| GET | `/cluster/options` | [get_options](endpoints/GET_cluster_options.md) | +| PUT | `/cluster/options` | [set_options](endpoints/PUT_cluster_options.md) | +| GET | `/cluster/qemu` | [index](endpoints/GET_cluster_qemu.md) | +| GET | `/cluster/qemu/cpu-flags` | [index](endpoints/GET_cluster_qemu_cpu_flags.md) | +| GET | `/cluster/qemu/custom-cpu-models` | [config](endpoints/GET_cluster_qemu_custom_cpu_models.md) | +| POST | `/cluster/qemu/custom-cpu-models` | [create](endpoints/POST_cluster_qemu_custom_cpu_models.md) | +| DELETE | `/cluster/qemu/custom-cpu-models/{cputype}` | [delete](endpoints/DELETE_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/qemu/custom-cpu-models/{cputype}` | [info](endpoints/GET_cluster_qemu_custom_cpu_models_cputype.md) | +| PUT | `/cluster/qemu/custom-cpu-models/{cputype}` | [update](endpoints/PUT_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/replication` | [index](endpoints/GET_cluster_replication.md) | +| POST | `/cluster/replication` | [create](endpoints/POST_cluster_replication.md) | +| DELETE | `/cluster/replication/{id}` | [delete](endpoints/DELETE_cluster_replication_id.md) | +| GET | `/cluster/replication/{id}` | [read](endpoints/GET_cluster_replication_id.md) | +| PUT | `/cluster/replication/{id}` | [update](endpoints/PUT_cluster_replication_id.md) | +| GET | `/cluster/resources` | [resources](endpoints/GET_cluster_resources.md) | +| GET | `/cluster/sdn` | [index](endpoints/GET_cluster_sdn.md) | +| PUT | `/cluster/sdn` | [reload](endpoints/PUT_cluster_sdn.md) | +| GET | `/cluster/sdn/controllers` | [index](endpoints/GET_cluster_sdn_controllers.md) | +| POST | `/cluster/sdn/controllers` | [create](endpoints/POST_cluster_sdn_controllers.md) | +| DELETE | `/cluster/sdn/controllers/{controller}` | [delete](endpoints/DELETE_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/controllers/{controller}` | [read](endpoints/GET_cluster_sdn_controllers_controller.md) | +| PUT | `/cluster/sdn/controllers/{controller}` | [update](endpoints/PUT_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/dns` | [index](endpoints/GET_cluster_sdn_dns.md) | +| POST | `/cluster/sdn/dns` | [create](endpoints/POST_cluster_sdn_dns.md) | +| DELETE | `/cluster/sdn/dns/{dns}` | [delete](endpoints/DELETE_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dns/{dns}` | [read](endpoints/GET_cluster_sdn_dns_dns.md) | +| PUT | `/cluster/sdn/dns/{dns}` | [update](endpoints/PUT_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dry-run` | [dry-run](endpoints/GET_cluster_sdn_dry_run.md) | +| GET | `/cluster/sdn/fabrics` | [index](endpoints/GET_cluster_sdn_fabrics.md) | +| GET | `/cluster/sdn/fabrics/all` | [list_all](endpoints/GET_cluster_sdn_fabrics_all.md) | +| GET | `/cluster/sdn/fabrics/fabric` | [index](endpoints/GET_cluster_sdn_fabrics_fabric.md) | +| POST | `/cluster/sdn/fabrics/fabric` | [add_fabric](endpoints/POST_cluster_sdn_fabrics_fabric.md) | +| DELETE | `/cluster/sdn/fabrics/fabric/{id}` | [delete_fabric](endpoints/DELETE_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/fabric/{id}` | [get_fabric](endpoints/GET_cluster_sdn_fabrics_fabric_id.md) | +| PUT | `/cluster/sdn/fabrics/fabric/{id}` | [update_fabric](endpoints/PUT_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/node` | [list_nodes](endpoints/GET_cluster_sdn_fabrics_node.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}` | [list_nodes_fabric](endpoints/GET_cluster_sdn_fabrics_node_fabric_id.md) | +| POST | `/cluster/sdn/fabrics/node/{fabric_id}` | [add_node](endpoints/POST_cluster_sdn_fabrics_node_fabric_id.md) | +| DELETE | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [delete_node](endpoints/DELETE_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [get_node](endpoints/GET_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| PUT | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [update_node](endpoints/PUT_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/ipams` | [index](endpoints/GET_cluster_sdn_ipams.md) | +| POST | `/cluster/sdn/ipams` | [create](endpoints/POST_cluster_sdn_ipams.md) | +| DELETE | `/cluster/sdn/ipams/{ipam}` | [delete](endpoints/DELETE_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}` | [read](endpoints/GET_cluster_sdn_ipams_ipam.md) | +| PUT | `/cluster/sdn/ipams/{ipam}` | [update](endpoints/PUT_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}/status` | [ipamindex](endpoints/GET_cluster_sdn_ipams_ipam_status.md) | +| DELETE | `/cluster/sdn/lock` | [release_lock](endpoints/DELETE_cluster_sdn_lock.md) | +| POST | `/cluster/sdn/lock` | [lock](endpoints/POST_cluster_sdn_lock.md) | +| GET | `/cluster/sdn/prefix-lists` | [list_prefix_lists](endpoints/GET_cluster_sdn_prefix_lists.md) | +| POST | `/cluster/sdn/prefix-lists` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}` | [delete_prefix_list](endpoints/DELETE_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}` | [get_prefix_list](endpoints/GET_cluster_sdn_prefix_lists_id.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}` | [update_prefix_list](endpoints/PUT_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries` | [get_prefix_list_entries](endpoints/GET_cluster_sdn_prefix_lists_id_entries.md) | +| POST | `/cluster/sdn/prefix-lists/{id}/entries` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists_id_entries.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [delete_prefix_list_entry](endpoints/DELETE_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [get_prefix_list_entry](endpoints/GET_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [update_prefix_list_entry](endpoints/PUT_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| POST | `/cluster/sdn/rollback` | [rollback](endpoints/POST_cluster_sdn_rollback.md) | +| GET | `/cluster/sdn/route-maps` | [list_route_maps](endpoints/GET_cluster_sdn_route_maps.md) | +| GET | `/cluster/sdn/route-maps/entries` | [list_route_map_entries](endpoints/GET_cluster_sdn_route_maps_entries.md) | +| POST | `/cluster/sdn/route-maps/entries` | [create_route_map_entry](endpoints/POST_cluster_sdn_route_maps_entries.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}` | [list_route_map_entries_for_route_map](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id.md) | +| DELETE | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [delete_route_map_entry](endpoints/DELETE_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [get_route_map_entry](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| PUT | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [update_route_map_entry](endpoints/PUT_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/vnets` | [index](endpoints/GET_cluster_sdn_vnets.md) | +| POST | `/cluster/sdn/vnets` | [create](endpoints/POST_cluster_sdn_vnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall` | [index](endpoints/GET_cluster_sdn_vnets_vnet_firewall.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/options` | [get_options](endpoints/GET_cluster_sdn_vnets_vnet_firewall_options.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/options` | [set_options](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_options.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [get_rules](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules.md) | +| POST | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [create_rule](endpoints/POST_cluster_sdn_vnets_vnet_firewall_rules.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/ips` | [ipdelete](endpoints/DELETE_cluster_sdn_vnets_vnet_ips.md) | +| POST | `/cluster/sdn/vnets/{vnet}/ips` | [ipcreate](endpoints/POST_cluster_sdn_vnets_vnet_ips.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/ips` | [ipupdate](endpoints/PUT_cluster_sdn_vnets_vnet_ips.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets` | [index](endpoints/GET_cluster_sdn_vnets_vnet_subnets.md) | +| POST | `/cluster/sdn/vnets/{vnet}/subnets` | [create](endpoints/POST_cluster_sdn_vnets_vnet_subnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/zones` | [index](endpoints/GET_cluster_sdn_zones.md) | +| POST | `/cluster/sdn/zones` | [create](endpoints/POST_cluster_sdn_zones.md) | +| DELETE | `/cluster/sdn/zones/{zone}` | [delete](endpoints/DELETE_cluster_sdn_zones_zone.md) | +| GET | `/cluster/sdn/zones/{zone}` | [read](endpoints/GET_cluster_sdn_zones_zone.md) | +| PUT | `/cluster/sdn/zones/{zone}` | [update](endpoints/PUT_cluster_sdn_zones_zone.md) | +| GET | `/cluster/status` | [get_status](endpoints/GET_cluster_status.md) | +| GET | `/cluster/tasks` | [tasks](endpoints/GET_cluster_tasks.md) | diff --git a/docs/pve-api/markdown/endpoints/DELETE_access_domains_realm.md b/docs/pve-api/markdown/endpoints/DELETE_access_domains_realm.md new file mode 100644 index 00000000000..4466981cf59 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_access_domains_realm.md @@ -0,0 +1,71 @@ +# DELETE /access/domains/{realm} + +Delete an authentication server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_access_groups_groupid.md b/docs/pve-api/markdown/endpoints/DELETE_access_groups_groupid.md new file mode 100644 index 00000000000..b21e6c61aa3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_access_groups_groupid.md @@ -0,0 +1,69 @@ +# DELETE /access/groups/{groupid} + +Delete group. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_access_roles_roleid.md b/docs/pve-api/markdown/endpoints/DELETE_access_roles_roleid.md new file mode 100644 index 00000000000..6e5c0f8d166 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_access_roles_roleid.md @@ -0,0 +1,69 @@ +# DELETE /access/roles/{roleid} + +Delete role. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_access_tfa_userid_id.md b/docs/pve-api/markdown/endpoints/DELETE_access_tfa_userid_id.md new file mode 100644 index 00000000000..784c68b4c86 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_access_tfa_userid_id.md @@ -0,0 +1,99 @@ +# DELETE /access/tfa/{userid}/{id} + +Delete a TFA entry by ID. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | A TFA entry id. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | no | The current password of the user performing the change. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_access_users_userid.md b/docs/pve-api/markdown/endpoints/DELETE_access_users_userid.md new file mode 100644 index 00000000000..fa2742b2e4a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_access_users_userid.md @@ -0,0 +1,83 @@ +# DELETE /access/users/{userid} + +Delete user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "userid-param", + "Realm.AllocateUser" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_access_users_userid_token_tokenid.md b/docs/pve-api/markdown/endpoints/DELETE_access_users_userid_token_tokenid.md new file mode 100644 index 00000000000..d522ab7529b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_access_users_userid_token_tokenid.md @@ -0,0 +1,89 @@ +# DELETE /access/users/{userid}/token/{tokenid} + +Remove API token for a specific user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_acme_account_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_acme_account_name.md new file mode 100644 index 00000000000..8840f2da440 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_acme_account_name.md @@ -0,0 +1,54 @@ +# DELETE /cluster/acme/account/{name} + +Deactivate existing ACME account at CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | no | ACME account config file name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_acme_plugins_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_acme_plugins_id.md new file mode 100644 index 00000000000..fa7a5abaf42 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_acme_plugins_id.md @@ -0,0 +1,70 @@ +# DELETE /cluster/acme/plugins/{id} + +Delete ACME plugin configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Unique identifier for ACME plugin instance. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_backup_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_backup_id.md new file mode 100644 index 00000000000..da8dc1dda9e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_backup_id.md @@ -0,0 +1,70 @@ +# DELETE /cluster/backup/{id} + +Delete vzdump backup job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_config_nodes_node.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_config_nodes_node.md new file mode 100644 index 00000000000..32a3fec1412 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_config_nodes_node.md @@ -0,0 +1,51 @@ +# DELETE /cluster/config/nodes/{node} + +Removes a node from the cluster configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_aliases_name.md new file mode 100644 index 00000000000..fd9544bd17b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_aliases_name.md @@ -0,0 +1,80 @@ +# DELETE /cluster/firewall/aliases/{name} + +Remove IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_groups_group.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_groups_group.md new file mode 100644 index 00000000000..6d9f8acd5d4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_groups_group.md @@ -0,0 +1,71 @@ +# DELETE /cluster/firewall/groups/{group} + +Delete security group. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_groups_group_pos.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_groups_group_pos.md new file mode 100644 index 00000000000..5d2982082cf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_groups_group_pos.md @@ -0,0 +1,89 @@ +# DELETE /cluster/firewall/groups/{group}/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_ipset_name.md new file mode 100644 index 00000000000..ff0f0de064c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_ipset_name.md @@ -0,0 +1,79 @@ +# DELETE /cluster/firewall/ipset/{name} + +Delete IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Delete all members of the IPSet, if there are any. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..4f9df8331a1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_ipset_name_cidr.md @@ -0,0 +1,87 @@ +# DELETE /cluster/firewall/ipset/{name}/{cidr} + +Remove IP or Network from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_rules_pos.md new file mode 100644 index 00000000000..3af661aee7f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_firewall_rules_pos.md @@ -0,0 +1,81 @@ +# DELETE /cluster/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_groups_group.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_groups_group.md new file mode 100644 index 00000000000..c4f865ef72d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_groups_group.md @@ -0,0 +1,70 @@ +# DELETE /cluster/ha/groups/{group} + +Delete ha group configuration. (deprecated in favor of HA rules) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_resources_sid.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_resources_sid.md new file mode 100644 index 00000000000..a251ba6c12f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_resources_sid.md @@ -0,0 +1,79 @@ +# DELETE /cluster/ha/resources/{sid} + +Delete resource configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| purge | boolean | no | Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_rules_rule.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_rules_rule.md new file mode 100644 index 00000000000..cf7f0f7b8fc --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_ha_rules_rule.md @@ -0,0 +1,70 @@ +# DELETE /cluster/ha/rules/{rule} + +Delete HA rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| rule | string | yes | HA rule identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_jobs_realm_sync_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_jobs_realm_sync_id.md new file mode 100644 index 00000000000..752f921a4d2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_jobs_realm_sync_id.md @@ -0,0 +1,69 @@ +# DELETE /cluster/jobs/realm-sync/{id} + +Delete realm-sync job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_dir_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_dir_id.md new file mode 100644 index 00000000000..b9032e0dde2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_dir_id.md @@ -0,0 +1,69 @@ +# DELETE /cluster/mapping/dir/{id} + +Remove directory mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_pci_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_pci_id.md new file mode 100644 index 00000000000..8a4632bd547 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_pci_id.md @@ -0,0 +1,69 @@ +# DELETE /cluster/mapping/pci/{id} + +Remove Hardware Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_usb_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_usb_id.md new file mode 100644 index 00000000000..34742094664 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_mapping_usb_id.md @@ -0,0 +1,69 @@ +# DELETE /cluster/mapping/usb/{id} + +Remove Hardware Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_metrics_server_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_metrics_server_id.md new file mode 100644 index 00000000000..40b7f870ba5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_metrics_server_id.md @@ -0,0 +1,69 @@ +# DELETE /cluster/metrics/server/{id} + +Remove Metric server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_gotify_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_gotify_name.md new file mode 100644 index 00000000000..d9e7c5eb270 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_gotify_name.md @@ -0,0 +1,69 @@ +# DELETE /cluster/notifications/endpoints/gotify/{name} + +Remove gotify endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_sendmail_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_sendmail_name.md new file mode 100644 index 00000000000..b7846e9ff56 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_sendmail_name.md @@ -0,0 +1,69 @@ +# DELETE /cluster/notifications/endpoints/sendmail/{name} + +Remove sendmail endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_smtp_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_smtp_name.md new file mode 100644 index 00000000000..a29a3ab0c58 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_smtp_name.md @@ -0,0 +1,69 @@ +# DELETE /cluster/notifications/endpoints/smtp/{name} + +Remove smtp endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_webhook_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_webhook_name.md new file mode 100644 index 00000000000..0df01283a21 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_endpoints_webhook_name.md @@ -0,0 +1,69 @@ +# DELETE /cluster/notifications/endpoints/webhook/{name} + +Remove webhook endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_matchers_name.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_matchers_name.md new file mode 100644 index 00000000000..66dc7c14f76 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_notifications_matchers_name.md @@ -0,0 +1,69 @@ +# DELETE /cluster/notifications/matchers/{name} + +Remove matcher + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_qemu_custom_cpu_models_cputype.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_qemu_custom_cpu_models_cputype.md new file mode 100644 index 00000000000..a0d4cdb32b7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_qemu_custom_cpu_models_cputype.md @@ -0,0 +1,69 @@ +# DELETE /cluster/qemu/custom-cpu-models/{cputype} + +Delete a custom CPU model definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | The custom model to delete. The 'custom-' prefix is optional. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_replication_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_replication_id.md new file mode 100644 index 00000000000..6e9c9087caa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_replication_id.md @@ -0,0 +1,77 @@ +# DELETE /cluster/replication/{id} + +Mark replication job for removal. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Will remove the jobconfig entry, but will not cleanup. | +| keep | boolean | no | Keep replicated data at target (do not remove). | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_controllers_controller.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_controllers_controller.md new file mode 100644 index 00000000000..1beb3f71cab --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_controllers_controller.md @@ -0,0 +1,79 @@ +# DELETE /cluster/sdn/controllers/{controller} + +Delete sdn controller object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_dns_dns.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_dns_dns.md new file mode 100644 index 00000000000..0841fbb2a82 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_dns_dns.md @@ -0,0 +1,78 @@ +# DELETE /cluster/sdn/dns/{dns} + +Delete sdn dns object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_fabrics_fabric_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_fabrics_fabric_id.md new file mode 100644 index 00000000000..e9a63e88f44 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_fabrics_fabric_id.md @@ -0,0 +1,71 @@ +# DELETE /cluster/sdn/fabrics/fabric/{id} + +Add a fabric + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_fabrics_node_fabric_id_node_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_fabrics_node_fabric_id_node_id.md new file mode 100644 index 00000000000..f8ace1f63f1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_fabrics_node_fabric_id_node_id.md @@ -0,0 +1,98 @@ +# DELETE /cluster/sdn/fabrics/node/{fabric_id}/{node_id} + +Add a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | +| node_id | string | yes | Identifier for nodes in an SDN fabric | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_ipams_ipam.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_ipams_ipam.md new file mode 100644 index 00000000000..fec6690f424 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_ipams_ipam.md @@ -0,0 +1,78 @@ +# DELETE /cluster/sdn/ipams/{ipam} + +Delete sdn ipam object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_lock.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_lock.md new file mode 100644 index 00000000000..f1b84d9b2b0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_lock.md @@ -0,0 +1,78 @@ +# DELETE /cluster/sdn/lock + +Release global lock for SDN configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | if true, allow releasing lock without providing the token | +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_prefix_lists_id.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_prefix_lists_id.md new file mode 100644 index 00000000000..2213fa0c210 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_prefix_lists_id.md @@ -0,0 +1,77 @@ +# DELETE /cluster/sdn/prefix-lists/{id} + +Delete Prefix List + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_prefix_lists_id_entries_url_seq.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_prefix_lists_id_entries_url_seq.md new file mode 100644 index 00000000000..696434896d0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_prefix_lists_id_entries_url_seq.md @@ -0,0 +1,77 @@ +# DELETE /cluster/sdn/prefix-lists/{id}/entries/{url_seq} + +Delete Prefix List Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_route_maps_entries_route_map_id_entry_order.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_route_maps_entries_route_map_id_entry_order.md new file mode 100644 index 00000000000..4b6a91c4322 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_route_maps_entries_route_map_id_entry_order.md @@ -0,0 +1,85 @@ +# DELETE /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order} + +Delete Route Map Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet.md new file mode 100644 index 00000000000..48e7e838096 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet.md @@ -0,0 +1,69 @@ +# DELETE /cluster/sdn/vnets/{vnet} + +Delete sdn vnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_firewall_rules_pos.md new file mode 100644 index 00000000000..e27dabb75a0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_firewall_rules_pos.md @@ -0,0 +1,79 @@ +# DELETE /cluster/sdn/vnets/{vnet}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_ips.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_ips.md new file mode 100644 index 00000000000..181a954ad06 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_ips.md @@ -0,0 +1,97 @@ +# DELETE /cluster/sdn/vnets/{vnet}/ips + +Delete IP Mappings in a VNet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ip | string | yes | The IP address to delete | +| zone | string | yes | The SDN zone object identifier. | +| mac | string | no | Unicast MAC address. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_subnets_subnet.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_subnets_subnet.md new file mode 100644 index 00000000000..b7411924be9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_vnets_vnet_subnets_subnet.md @@ -0,0 +1,76 @@ +# DELETE /cluster/sdn/vnets/{vnet}/subnets/{subnet} + +Delete sdn subnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_zones_zone.md b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_zones_zone.md new file mode 100644 index 00000000000..c3cfe88ba2f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_cluster_sdn_zones_zone.md @@ -0,0 +1,79 @@ +# DELETE /cluster/sdn/zones/{zone} + +Delete sdn zone object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_fs_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_fs_name.md new file mode 100644 index 00000000000..ee2eeafc5c0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_fs_name.md @@ -0,0 +1,94 @@ +# DELETE /nodes/{node}/ceph/fs/{name} + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The Ceph filesystem name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| remove-pools | boolean | no | Remove the metadata and data pools used by this filesystem. | +| remove-storages | boolean | no | Remove pveceph-managed storages configured for this filesystem. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mds_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mds_name.md new file mode 100644 index 00000000000..8beb5d3a52c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mds_name.md @@ -0,0 +1,77 @@ +# DELETE /nodes/{node}/ceph/mds/{name} + +Destroy Ceph Metadata Server + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name (ID) of the mds | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mgr_id.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mgr_id.md new file mode 100644 index 00000000000..fef7f56c4ce --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mgr_id.md @@ -0,0 +1,77 @@ +# DELETE /nodes/{node}/ceph/mgr/{id} + +Destroy Ceph Manager. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the manager | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mon_monid.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mon_monid.md new file mode 100644 index 00000000000..ff29d3f1646 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_mon_monid.md @@ -0,0 +1,77 @@ +# DELETE /nodes/{node}/ceph/mon/{monid} + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| monid | string | yes | Monitor ID | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_osd_osdid.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_osd_osdid.md new file mode 100644 index 00000000000..e7867d7edb6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_osd_osdid.md @@ -0,0 +1,67 @@ +# DELETE /nodes/{node}/ceph/osd/{osdid} + +Destroy OSD + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup | boolean | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_pool_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_pool_name.md new file mode 100644 index 00000000000..f7089e2a798 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_ceph_pool_name.md @@ -0,0 +1,102 @@ +# DELETE /nodes/{node}/ceph/pool/{name} + +Destroy pool + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | If true, destroys pool even if in use | +| remove_ecprofile | boolean | no | Remove the erasure code profile. Defaults to true, if applicable. | +| remove_storages | boolean | no | Remove all pveceph-managed storages configured for this pool | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_certificates_acme_certificate.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_certificates_acme_certificate.md new file mode 100644 index 00000000000..e0a8386c931 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_certificates_acme_certificate.md @@ -0,0 +1,71 @@ +# DELETE /nodes/{node}/certificates/acme/certificate + +Revoke existing certificate from CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_certificates_custom.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_certificates_custom.md new file mode 100644 index 00000000000..3b47d219127 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_certificates_custom.md @@ -0,0 +1,80 @@ +# DELETE /nodes/{node}/certificates/custom + +DELETE custom certificate chain and key. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| restart | boolean | no | Restart pveproxy. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_directory_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_directory_name.md new file mode 100644 index 00000000000..bd5d01ba92c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_directory_name.md @@ -0,0 +1,98 @@ +# DELETE /nodes/{node}/disks/directory/{name} + +Unmounts the storage and removes the mount unit. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disk so it can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_lvm_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_lvm_name.md new file mode 100644 index 00000000000..cd04df07e3a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_lvm_name.md @@ -0,0 +1,98 @@ +# DELETE /nodes/{node}/disks/lvm/{name} + +Remove an LVM Volume Group. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disks so they can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_lvmthin_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_lvmthin_name.md new file mode 100644 index 00000000000..899397b6f6e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_lvmthin_name.md @@ -0,0 +1,106 @@ +# DELETE /nodes/{node}/disks/lvmthin/{name} + +Remove an LVM thin pool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume-group | string | yes | The storage identifier. | +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disks so they can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_zfs_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_zfs_name.md new file mode 100644 index 00000000000..496bb30c003 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_disks_zfs_name.md @@ -0,0 +1,98 @@ +# DELETE /nodes/{node}/disks/zfs/{name} + +Destroy a ZFS pool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cleanup-config | boolean | no | Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only). | +| cleanup-disks | boolean | no | Also wipe disks so they can be repurposed afterwards. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'cleanup-config'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_firewall_rules_pos.md new file mode 100644 index 00000000000..2bdfcd50573 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_firewall_rules_pos.md @@ -0,0 +1,88 @@ +# DELETE /nodes/{node}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid.md new file mode 100644 index 00000000000..46c3686aea7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid.md @@ -0,0 +1,104 @@ +# DELETE /nodes/{node}/lxc/{vmid} + +Destroy the container (also delete all uses files). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| destroy-unreferenced-disks | boolean | no | If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config. | +| force | boolean | no | Force destroy, even if running. | +| purge | boolean | no | Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_aliases_name.md new file mode 100644 index 00000000000..66954bfa111 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_aliases_name.md @@ -0,0 +1,96 @@ +# DELETE /nodes/{node}/lxc/{vmid}/firewall/aliases/{name} + +Remove IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name.md new file mode 100644 index 00000000000..7c162ac2379 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name.md @@ -0,0 +1,95 @@ +# DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name} + +Delete IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Delete all members of the IPSet, if there are any. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..ff5f80b4531 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md @@ -0,0 +1,103 @@ +# DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr} + +Remove IP or Network from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_rules_pos.md new file mode 100644 index 00000000000..0f2d82eca57 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_firewall_rules_pos.md @@ -0,0 +1,97 @@ +# DELETE /nodes/{node}/lxc/{vmid}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_snapshot_snapname.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_snapshot_snapname.md new file mode 100644 index 00000000000..200dce0471b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_lxc_vmid_snapshot_snapname.md @@ -0,0 +1,98 @@ +# DELETE /nodes/{node}/lxc/{vmid}/snapshot/{snapname} + +Delete a LXC snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | For removal from config file, even if removing disk snapshots fails. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_network.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_network.md new file mode 100644 index 00000000000..05d0e13483d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_network.md @@ -0,0 +1,71 @@ +# DELETE /nodes/{node}/network + +Revert network configuration changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_network_iface.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_network_iface.md new file mode 100644 index 00000000000..75b76cfd830 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_network_iface.md @@ -0,0 +1,80 @@ +# DELETE /nodes/{node}/network/{iface} + +Delete network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid.md new file mode 100644 index 00000000000..a7996a70607 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid.md @@ -0,0 +1,103 @@ +# DELETE /nodes/{node}/qemu/{vmid} + +Destroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| destroy-unreferenced-disks | boolean | no | If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages. | +| purge | boolean | no | Remove VMID from configurations, like backup & replication jobs and HA. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_aliases_name.md new file mode 100644 index 00000000000..49770b067c6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_aliases_name.md @@ -0,0 +1,96 @@ +# DELETE /nodes/{node}/qemu/{vmid}/firewall/aliases/{name} + +Remove IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name.md new file mode 100644 index 00000000000..bcfa3a97513 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name.md @@ -0,0 +1,95 @@ +# DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name} + +Delete IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Delete all members of the IPSet, if there are any. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..134acb651f6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md @@ -0,0 +1,103 @@ +# DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr} + +Remove IP or Network from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_rules_pos.md new file mode 100644 index 00000000000..ec76b415d04 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_firewall_rules_pos.md @@ -0,0 +1,97 @@ +# DELETE /nodes/{node}/qemu/{vmid}/firewall/rules/{pos} + +Delete rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_snapshot_snapname.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_snapshot_snapname.md new file mode 100644 index 00000000000..743f7b32b9c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_qemu_vmid_snapshot_snapname.md @@ -0,0 +1,98 @@ +# DELETE /nodes/{node}/qemu/{vmid}/snapshot/{snapname} + +Delete a VM snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | For removal from config file, even if removing disk snapshots fails. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_storage_storage_content_volume.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_storage_storage_content_volume.md new file mode 100644 index 00000000000..fa081cfe783 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_storage_storage_content_volume.md @@ -0,0 +1,88 @@ +# DELETE /nodes/{node}/storage/{storage}/content/{volume} + +Delete volume + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delay | integer | no | Time to wait for the task to finish. We return 'null' if the task finish within that time. | + +## Returns + +```json +{ + "optional": 1, + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_storage_storage_prunebackups.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_storage_storage_prunebackups.md new file mode 100644 index 00000000000..ed01d08c367 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_storage_storage_prunebackups.md @@ -0,0 +1,98 @@ +# DELETE /nodes/{node}/storage/{storage}/prunebackups + +Prune backups. Only those using the standard naming scheme are considered. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| type | string | no | Either 'qemu' or 'lxc'. Only consider backups for guests of this type. | +| vmid | integer | no | Only prune backups for this VM. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_subscription.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_subscription.md new file mode 100644 index 00000000000..a6324ff8567 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_subscription.md @@ -0,0 +1,71 @@ +# DELETE /nodes/{node}/subscription + +Delete subscription key of this node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_nodes_node_tasks_upid.md b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_tasks_upid.md new file mode 100644 index 00000000000..012c44469fa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_nodes_node_tasks_upid.md @@ -0,0 +1,66 @@ +# DELETE /nodes/{node}/tasks/{upid} + +Stop a task. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Modify' permissions on '/nodes/' if they aren't the owner of the task.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_pools.md b/docs/pve-api/markdown/endpoints/DELETE_pools.md new file mode 100644 index 00000000000..b4a80496bd7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_pools.md @@ -0,0 +1,71 @@ +# DELETE /pools + +Delete pool. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You can only delete empty pools (no members)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_pools_poolid.md b/docs/pve-api/markdown/endpoints/DELETE_pools_poolid.md new file mode 100644 index 00000000000..b406226c6db --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_pools_poolid.md @@ -0,0 +1,71 @@ +# DELETE /pools/{poolid} + +Delete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}'). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You can only delete empty pools (no members)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/DELETE_storage_storage.md b/docs/pve-api/markdown/endpoints/DELETE_storage_storage.md new file mode 100644 index 00000000000..c9cb1303272 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/DELETE_storage_storage.md @@ -0,0 +1,71 @@ +# DELETE /storage/{storage} + +Delete storage configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access.md b/docs/pve-api/markdown/endpoints/GET_access.md new file mode 100644 index 00000000000..d70b601d388 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access.md @@ -0,0 +1,75 @@ +# GET /access + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_acl.md b/docs/pve-api/markdown/endpoints/GET_access_acl.md new file mode 100644 index 00000000000..dfea50baf9a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_acl.md @@ -0,0 +1,109 @@ +# GET /access/acl + +Get Access Control List (ACLs). + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "The returned list is restricted to objects where you have rights to modify permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_domains.md b/docs/pve-api/markdown/endpoints/GET_access_domains.md new file mode 100644 index 00000000000..e0b13f9c736 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_domains.md @@ -0,0 +1,111 @@ +# GET /access/domains + +Authentication domain index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Anyone can access that, because we need that list for the login box (before the user is authenticated).", + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_domains_realm.md b/docs/pve-api/markdown/endpoints/GET_access_domains_realm.md new file mode 100644 index 00000000000..c7998764af4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_domains_realm.md @@ -0,0 +1,72 @@ +# GET /access/domains/{realm} + +Get auth server configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +None. + +## Returns + +```json +{} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate", + "Sys.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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": {} +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_groups.md b/docs/pve-api/markdown/endpoints/GET_access_groups.md new file mode 100644 index 00000000000..e8d5c079c00 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_groups.md @@ -0,0 +1,99 @@ +# GET /access/groups + +Group index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "The returned list is restricted to groups where you have 'User.Modify', 'Sys.Audit' or 'Group.Allocate' permissions on /access/groups/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_groups_groupid.md b/docs/pve-api/markdown/endpoints/GET_access_groups_groupid.md new file mode 100644 index 00000000000..abce10d95e1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_groups_groupid.md @@ -0,0 +1,106 @@ +# GET /access/groups/{groupid} + +Get group configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Sys.Audit", + "Group.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_openid.md b/docs/pve-api/markdown/endpoints/GET_access_openid.md new file mode 100644 index 00000000000..61293cd7d97 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_openid.md @@ -0,0 +1,75 @@ +# GET /access/openid + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_permissions.md b/docs/pve-api/markdown/endpoints/GET_access_permissions.md new file mode 100644 index 00000000000..86e22f30ad1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_permissions.md @@ -0,0 +1,68 @@ +# GET /access/permissions + +Retrieve effective permissions of given user/token. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| path | string | no | Only dump this specific path, not the whole tree. | +| userid | string | no | User ID or full API token ID | + +## Returns + +```json +{ + "description": "Map of \"path\" => (Map of \"privilege\" => \"propagate boolean\").", + "type": "object" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_roles.md b/docs/pve-api/markdown/endpoints/GET_access_roles.md new file mode 100644 index 00000000000..ba0d85f0d20 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_roles.md @@ -0,0 +1,97 @@ +# GET /access/roles + +Role index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_roles_roleid.md b/docs/pve-api/markdown/endpoints/GET_access_roles_roleid.md new file mode 100644 index 00000000000..c1141d816e4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_roles_roleid.md @@ -0,0 +1,438 @@ +# GET /access/roles/{roleid} + +Get role configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_tfa.md b/docs/pve-api/markdown/endpoints/GET_access_tfa.md new file mode 100644 index 00000000000..76356b8a3eb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_tfa.md @@ -0,0 +1,178 @@ +# GET /access/tfa + +List TFA configurations of users. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Returns all or just the logged-in user, depending on privileges.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_tfa_userid.md b/docs/pve-api/markdown/endpoints/GET_access_tfa_userid.md new file mode 100644 index 00000000000..2b2a6e1d298 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_tfa_userid.md @@ -0,0 +1,169 @@ +# GET /access/tfa/{userid} + +List TFA configurations of users. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_tfa_userid_id.md b/docs/pve-api/markdown/endpoints/GET_access_tfa_userid_id.md new file mode 100644 index 00000000000..6ab2d91db8c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_tfa_userid_id.md @@ -0,0 +1,155 @@ +# GET /access/tfa/{userid}/{id} + +Fetch a requested TFA entry if present. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | A TFA entry id. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_ticket.md b/docs/pve-api/markdown/endpoints/GET_access_ticket.md new file mode 100644 index 00000000000..7022549daeb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_ticket.md @@ -0,0 +1,47 @@ +# GET /access/ticket + +Dummy. Useful for formatters which want to provide a login page. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_users.md b/docs/pve-api/markdown/endpoints/GET_access_users.md new file mode 100644 index 00000000000..ee9cd4b4bb9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_users.md @@ -0,0 +1,284 @@ +# GET /access/users + +User index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| enabled | boolean | no | Optional filter for enable property. | +| full | boolean | no | Include group and token information. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_users_userid.md b/docs/pve-api/markdown/endpoints/GET_access_users_userid.md new file mode 100644 index 00000000000..12a8e9bd4b7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_users_userid.md @@ -0,0 +1,222 @@ +# GET /access/users/{userid} + +Get user configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_users_userid_tfa.md b/docs/pve-api/markdown/endpoints/GET_access_users_userid_tfa.md new file mode 100644 index 00000000000..4e7dc688a4c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_users_userid_tfa.md @@ -0,0 +1,168 @@ +# GET /access/users/{userid}/tfa + +Get user TFA types (Personal and Realm). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| multiple | boolean | no | Request all entries as an array. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify", + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_users_userid_token.md b/docs/pve-api/markdown/endpoints/GET_access_users_userid_token.md new file mode 100644 index 00000000000..6908521e5f8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_users_userid_token.md @@ -0,0 +1,148 @@ +# GET /access/users/{userid}/token + +Get user API tokens. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_access_users_userid_token_tokenid.md b/docs/pve-api/markdown/endpoints/GET_access_users_userid_token_tokenid.md new file mode 100644 index 00000000000..1ef9a2e7d0c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_access_users_userid_token_tokenid.md @@ -0,0 +1,126 @@ +# GET /access/users/{userid}/token/{tokenid} + +Get specific API token information. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster.md b/docs/pve-api/markdown/endpoints/GET_cluster.md new file mode 100644 index 00000000000..5b2509bfdaa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster.md @@ -0,0 +1,67 @@ +# GET /cluster + +Cluster index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme.md new file mode 100644 index 00000000000..d5865862d10 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme.md @@ -0,0 +1,67 @@ +# GET /cluster/acme + +ACMEAccount index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_account.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_account.md new file mode 100644 index 00000000000..bb8729b6625 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_account.md @@ -0,0 +1,68 @@ +# GET /cluster/acme/account + +ACMEAccount index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_account_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_account_name.md new file mode 100644 index 00000000000..26dcef94813 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_account_name.md @@ -0,0 +1,98 @@ +# GET /cluster/acme/account/{name} + +Return existing ACME account information. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | no | ACME account config file name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_challenge_schema.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_challenge_schema.md new file mode 100644 index 00000000000..d3ee57ef0dc --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_challenge_schema.md @@ -0,0 +1,85 @@ +# GET /cluster/acme/challenge-schema + +Get schema of ACME challenge types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_directories.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_directories.md new file mode 100644 index 00000000000..8dd2c3db2f5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_directories.md @@ -0,0 +1,75 @@ +# GET /cluster/acme/directories + +Get named known ACME directory endpoints. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "additionalProperties": 0, + "properties": { + "name": { + "type": "string" + }, + "url": { + "description": "URL of ACME CA directory endpoint.", + "pattern": "^https?://.*", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_meta.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_meta.md new file mode 100644 index 00000000000..d6321b559c3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_meta.md @@ -0,0 +1,122 @@ +# GET /cluster/acme/meta + +Retrieve ACME Directory Meta Information + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| directory | string | no | URL of ACME CA directory endpoint. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_plugins.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_plugins.md new file mode 100644 index 00000000000..4a5ab9a09fc --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_plugins.md @@ -0,0 +1,515 @@ +# GET /cluster/acme/plugins + +ACME plugin index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list ACME plugins of a specific type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_plugins_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_plugins_id.md new file mode 100644 index 00000000000..78d5b2be5d8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_plugins_id.md @@ -0,0 +1,494 @@ +# GET /cluster/acme/plugins/{id} + +Get ACME plugin configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Unique identifier for ACME plugin instance. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_acme_tos.md b/docs/pve-api/markdown/endpoints/GET_cluster_acme_tos.md new file mode 100644 index 00000000000..ef5024efdbf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_acme_tos.md @@ -0,0 +1,62 @@ +# GET /cluster/acme/tos + +Retrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| directory | string | no | URL of ACME CA directory endpoint. | + +## Returns + +```json +{ + "description": "ACME TermsOfService URL.", + "optional": 1, + "type": "string" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_backup.md b/docs/pve-api/markdown/endpoints/GET_cluster_backup.md new file mode 100644 index 00000000000..61e5c229e8c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_backup.md @@ -0,0 +1,743 @@ +# GET /cluster/backup + +List vzdump backup schedule. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_backup_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_backup_id.md new file mode 100644 index 00000000000..02f1295f2c4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_backup_id.md @@ -0,0 +1,735 @@ +# GET /cluster/backup/{id} + +Read vzdump backup job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_backup_id_included_volumes.md b/docs/pve-api/markdown/endpoints/GET_cluster_backup_id_included_volumes.md new file mode 100644 index 00000000000..5fc10a270ce --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_backup_id_included_volumes.md @@ -0,0 +1,180 @@ +# GET /cluster/backup/{id}/included_volumes + +Returns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_backup_info.md b/docs/pve-api/markdown/endpoints/GET_cluster_backup_info.md new file mode 100644 index 00000000000..865fb505183 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_backup_info.md @@ -0,0 +1,72 @@ +# GET /cluster/backup-info + +Index for backup info related endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Directory index.", + "items": { + "properties": { + "subdir": { + "description": "API sub-directory endpoint", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_backup_info_not_backed_up.md b/docs/pve-api/markdown/endpoints/GET_cluster_backup_info_not_backed_up.md new file mode 100644 index 00000000000..756563db57a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_backup_info_not_backed_up.md @@ -0,0 +1,106 @@ +# GET /cluster/backup-info/not-backed-up + +Shows all guests which are not covered by any backup job. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_bulk_action.md b/docs/pve-api/markdown/endpoints/GET_cluster_bulk_action.md new file mode 100644 index 00000000000..23aeb1edf2b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_bulk_action.md @@ -0,0 +1,65 @@ +# GET /cluster/bulk-action + +List resource types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_bulk_action_guest.md b/docs/pve-api/markdown/endpoints/GET_cluster_bulk_action_guest.md new file mode 100644 index 00000000000..8550592494b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_bulk_action_guest.md @@ -0,0 +1,67 @@ +# GET /cluster/bulk-action/guest + +Bulk action index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ceph.md b/docs/pve-api/markdown/endpoints/GET_cluster_ceph.md new file mode 100644 index 00000000000..2cbfb00559c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ceph.md @@ -0,0 +1,67 @@ +# GET /cluster/ceph + +Cluster ceph index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ceph_flags.md b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_flags.md new file mode 100644 index 00000000000..79efccf031c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_flags.md @@ -0,0 +1,134 @@ +# GET /cluster/ceph/flags + +get the status of all ceph flags + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ceph_flags_flag.md b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_flags_flag.md new file mode 100644 index 00000000000..5ddcdc82057 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_flags_flag.md @@ -0,0 +1,81 @@ +# GET /cluster/ceph/flags/{flag} + +Get the status of a specific ceph flag. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| flag | string | yes | The name of the flag name to get. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "boolean" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ceph_metadata.md b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_metadata.md new file mode 100644 index 00000000000..c494abe2dac --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_metadata.md @@ -0,0 +1,558 @@ +# GET /cluster/ceph/metadata + +Get ceph metadata. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| scope | string | no | 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. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ceph_status.md b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_status.md new file mode 100644 index 00000000000..0a0c357129b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ceph_status.md @@ -0,0 +1,66 @@ +# GET /cluster/ceph/status + +Get ceph status. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_config.md b/docs/pve-api/markdown/endpoints/GET_cluster_config.md new file mode 100644 index 00000000000..3533fbfd0ec --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_config.md @@ -0,0 +1,79 @@ +# GET /cluster/config + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_config_apiversion.md b/docs/pve-api/markdown/endpoints/GET_cluster_config_apiversion.md new file mode 100644 index 00000000000..23351d039c2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_config_apiversion.md @@ -0,0 +1,63 @@ +# GET /cluster/config/apiversion + +Return the version of the cluster join API available on this node. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Cluster Join API version, currently 1", + "minimum": 0, + "type": "integer" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_config_join.md b/docs/pve-api/markdown/endpoints/GET_cluster_config_join.md new file mode 100644 index 00000000000..3018e295896 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_config_join.md @@ -0,0 +1,209 @@ +# GET /cluster/config/join + +Get information needed to join this cluster over the connected node. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | no | The node for which the joinee gets the nodeinfo. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_config_nodes.md b/docs/pve-api/markdown/endpoints/GET_cluster_config_nodes.md new file mode 100644 index 00000000000..c53730f16d7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_config_nodes.md @@ -0,0 +1,87 @@ +# GET /cluster/config/nodes + +Corosync node list. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "node": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{node}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_config_qdevice.md b/docs/pve-api/markdown/endpoints/GET_cluster_config_qdevice.md new file mode 100644 index 00000000000..c98cea8f951 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_config_qdevice.md @@ -0,0 +1,60 @@ +# GET /cluster/config/qdevice + +Get QDevice status + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "allowtoken": 1, + "description": "Get QDevice status", + "method": "GET", + "name": "status", + "parameters": { + "additionalProperties": 0 + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "protected": 1, + "returns": { + "type": "object" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_config_totem.md b/docs/pve-api/markdown/endpoints/GET_cluster_config_totem.md new file mode 100644 index 00000000000..be1a4ef1fa0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_config_totem.md @@ -0,0 +1,59 @@ +# GET /cluster/config/totem + +Get corosync totem protocol settings. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "allowtoken": 1, + "description": "Get corosync totem protocol settings.", + "method": "GET", + "name": "totem", + "parameters": { + "additionalProperties": 0 + }, + "permissions": { + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] + }, + "returns": { + "type": "object" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall.md new file mode 100644 index 00000000000..928291c8344 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall.md @@ -0,0 +1,67 @@ +# GET /cluster/firewall + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_aliases.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_aliases.md new file mode 100644 index 00000000000..4cf4a618647 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_aliases.md @@ -0,0 +1,113 @@ +# GET /cluster/firewall/aliases + +List aliases + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_aliases_name.md new file mode 100644 index 00000000000..ffb54806ec1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_aliases_name.md @@ -0,0 +1,70 @@ +# GET /cluster/firewall/aliases/{name} + +Read alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups.md new file mode 100644 index 00000000000..7b9c987198c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups.md @@ -0,0 +1,103 @@ +# GET /cluster/firewall/groups + +List security groups. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups_group.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups_group.md new file mode 100644 index 00000000000..caab6e27bce --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups_group.md @@ -0,0 +1,259 @@ +# GET /cluster/firewall/groups/{group} + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups_group_pos.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups_group_pos.md new file mode 100644 index 00000000000..b0efefbd444 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_groups_group_pos.md @@ -0,0 +1,249 @@ +# GET /cluster/firewall/groups/{group}/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset.md new file mode 100644 index 00000000000..ae5df5092a4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset.md @@ -0,0 +1,115 @@ +# GET /cluster/firewall/ipset + +List IPSets + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset_name.md new file mode 100644 index 00000000000..4cc0b4a2ebb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset_name.md @@ -0,0 +1,126 @@ +# GET /cluster/firewall/ipset/{name} + +List IPSet content + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..dd635851aba --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_ipset_name_cidr.md @@ -0,0 +1,78 @@ +# GET /cluster/firewall/ipset/{name}/{cidr} + +Read IP or Network settings from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_macros.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_macros.md new file mode 100644 index 00000000000..5092a5d0676 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_macros.md @@ -0,0 +1,73 @@ +# GET /cluster/firewall/macros + +List available macros + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "descr": { + "description": "More verbose description (if available).", + "type": "string" + }, + "macro": { + "description": "Macro name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_options.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_options.md new file mode 100644 index 00000000000..559fd8889ae --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_options.md @@ -0,0 +1,203 @@ +# GET /cluster/firewall/options + +Get Firewall options. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_refs.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_refs.md new file mode 100644 index 00000000000..1e194787fbd --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_refs.md @@ -0,0 +1,122 @@ +# GET /cluster/firewall/refs + +Lists possible IPSet/Alias reference which are allowed in source/dest properties. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list references of specified type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_rules.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_rules.md new file mode 100644 index 00000000000..9f8b1ca7eb7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_rules.md @@ -0,0 +1,248 @@ +# GET /cluster/firewall/rules + +List rules. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_rules_pos.md new file mode 100644 index 00000000000..ea8a6a31385 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_firewall_rules_pos.md @@ -0,0 +1,241 @@ +# GET /cluster/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha.md new file mode 100644 index 00000000000..83ed245645c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha.md @@ -0,0 +1,87 @@ +# GET /cluster/ha + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_groups.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_groups.md new file mode 100644 index 00000000000..7629d7f2c33 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_groups.md @@ -0,0 +1,87 @@ +# GET /cluster/ha/groups + +Get HA groups. (deprecated in favor of HA rules) + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "group": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{group}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_groups_group.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_groups_group.md new file mode 100644 index 00000000000..16ee503f3b9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_groups_group.md @@ -0,0 +1,65 @@ +# GET /cluster/ha/groups/{group} + +Read ha group configuration. (deprecated in favor of HA rules) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | + +## Request parameters + +None. + +## Returns + +```json +{} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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": {} +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_resources.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_resources.md new file mode 100644 index 00000000000..c38fc2aab48 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_resources.md @@ -0,0 +1,100 @@ +# GET /cluster/ha/resources + +List HA resources. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list resources of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "sid": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{sid}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_resources_sid.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_resources_sid.md new file mode 100644 index 00000000000..fde95cea549 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_resources_sid.md @@ -0,0 +1,191 @@ +# GET /cluster/ha/resources/{sid} + +Read resource configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_rules.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_rules.md new file mode 100644 index 00000000000..49225586b0d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_rules.md @@ -0,0 +1,107 @@ +# GET /cluster/ha/rules + +Get HA rules. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| resource | string | no | Limit the returned list to rules affecting the specified resource. | +| type | string | no | Limit the returned list to the specified rule type. | + +## Returns + +```json +{ + "items": { + "links": [ + { + "href": "{rule}", + "rel": "child" + } + ], + "properties": { + "rule": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_rules_rule.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_rules_rule.md new file mode 100644 index 00000000000..996ea2efcb9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_rules_rule.md @@ -0,0 +1,99 @@ +# GET /cluster/ha/rules/{rule} + +Read HA rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| rule | string | yes | HA rule identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_status.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_status.md new file mode 100644 index 00000000000..617ec36f9cf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_status.md @@ -0,0 +1,67 @@ +# GET /cluster/ha/status + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_status_current.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_status_current.md new file mode 100644 index 00000000000..31591299d7a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_status_current.md @@ -0,0 +1,257 @@ +# GET /cluster/ha/status/current + +Get HA manager status. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_ha_status_manager_status.md b/docs/pve-api/markdown/endpoints/GET_cluster_ha_status_manager_status.md new file mode 100644 index 00000000000..9edc269f254 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_ha_status_manager_status.md @@ -0,0 +1,59 @@ +# GET /cluster/ha/status/manager_status + +Get full HA manager status, including LRM status. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_jobs.md b/docs/pve-api/markdown/endpoints/GET_cluster_jobs.md new file mode 100644 index 00000000000..8101207912d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_jobs.md @@ -0,0 +1,79 @@ +# GET /cluster/jobs + +Index for jobs related endpoints. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Directory index.", + "items": { + "properties": { + "subdir": { + "description": "API sub-directory endpoint", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_jobs_realm_sync.md b/docs/pve-api/markdown/endpoints/GET_cluster_jobs_realm_sync.md new file mode 100644 index 00000000000..e14cdf390d6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_jobs_realm_sync.md @@ -0,0 +1,183 @@ +# GET /cluster/jobs/realm-sync + +List configured realm-sync-jobs. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_jobs_realm_sync_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_jobs_realm_sync_id.md new file mode 100644 index 00000000000..16ade2bf366 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_jobs_realm_sync_id.md @@ -0,0 +1,68 @@ +# GET /cluster/jobs/realm-sync/{id} + +Read realm-sync job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_jobs_schedule_analyze.md b/docs/pve-api/markdown/endpoints/GET_cluster_jobs_schedule_analyze.md new file mode 100644 index 00000000000..edb709edac2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_jobs_schedule_analyze.md @@ -0,0 +1,103 @@ +# GET /cluster/jobs/schedule-analyze + +Returns a list of future schedule runtimes. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| schedule | string | yes | Job schedule. The format is a subset of `systemd` calendar events. | +| iterations | integer | no | Number of event-iteration to simulate and return. | +| starttime | integer | no | UNIX timestamp to start the calculation from. Defaults to the current time. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_log.md b/docs/pve-api/markdown/endpoints/GET_cluster_log.md new file mode 100644 index 00000000000..8ef3999ff5d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_log.md @@ -0,0 +1,68 @@ +# GET /cluster/log + +Read cluster log + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max | integer | no | Maximum number of entries. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Syslog' on '/' in order to get all logs.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_mapping.md b/docs/pve-api/markdown/endpoints/GET_cluster_mapping.md new file mode 100644 index 00000000000..39fc7c7fd14 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_mapping.md @@ -0,0 +1,65 @@ +# GET /cluster/mapping + +List resource types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_mapping_dir.md b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_dir.md new file mode 100644 index 00000000000..ff22eedfaa0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_dir.md @@ -0,0 +1,158 @@ +# GET /cluster/mapping/dir + +List directory mapping + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| check-node | string | no | If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/dir/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_mapping_dir_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_dir_id.md new file mode 100644 index 00000000000..7e3b8eb6dc3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_dir_id.md @@ -0,0 +1,103 @@ +# GET /cluster/mapping/dir/{id} + +Get directory mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_mapping_pci.md b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_pci.md new file mode 100644 index 00000000000..657f9a5931c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_pci.md @@ -0,0 +1,158 @@ +# GET /cluster/mapping/pci + +List PCI Hardware Mapping + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| check-node | string | no | If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/pci/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_mapping_pci_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_pci_id.md new file mode 100644 index 00000000000..1b94f7acc0a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_pci_id.md @@ -0,0 +1,103 @@ +# GET /cluster/mapping/pci/{id} + +Get PCI Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_mapping_usb.md b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_usb.md new file mode 100644 index 00000000000..7ba80102e6d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_usb.md @@ -0,0 +1,146 @@ +# GET /cluster/mapping/usb + +List USB Hardware Mappings + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| check-node | string | no | If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/usb/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_mapping_usb_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_usb_id.md new file mode 100644 index 00000000000..2d100f178b7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_mapping_usb_id.md @@ -0,0 +1,103 @@ +# GET /cluster/mapping/usb/{id} + +Get USB Mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_metrics.md b/docs/pve-api/markdown/endpoints/GET_cluster_metrics.md new file mode 100644 index 00000000000..0316838b4b1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_metrics.md @@ -0,0 +1,67 @@ +# GET /cluster/metrics + +Metrics index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_metrics_export.md b/docs/pve-api/markdown/endpoints/GET_cluster_metrics_export.md new file mode 100644 index 00000000000..86dbb8919a9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_metrics_export.md @@ -0,0 +1,170 @@ +# GET /cluster/metrics/export + +Retrieve metrics of the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| history | boolean | no | Also return historic values. Returns full available metric history unless `start-time` is also set | +| local-only | boolean | no | Only return metrics for the current node instead of the whole cluster | +| node-list | string | no | Only return metrics from nodes passed as comma-separated list | +| start-time | integer | no | Only include metrics with a timestamp > start-time. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_metrics_server.md b/docs/pve-api/markdown/endpoints/GET_cluster_metrics_server.md new file mode 100644 index 00000000000..6be54cb9010 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_metrics_server.md @@ -0,0 +1,121 @@ +# GET /cluster/metrics/server + +List configured metric servers. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_metrics_server_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_metrics_server_id.md new file mode 100644 index 00000000000..5a065cf0911 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_metrics_server_id.md @@ -0,0 +1,68 @@ +# GET /cluster/metrics/server/{id} + +Read metric server configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_nextid.md b/docs/pve-api/markdown/endpoints/GET_cluster_nextid.md new file mode 100644 index 00000000000..95a365f20ec --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_nextid.md @@ -0,0 +1,62 @@ +# GET /cluster/nextid + +Get next free VMID. Pass a VMID to assert that its free (at time of check). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "description": "The next free VMID.", + "type": "integer" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications.md new file mode 100644 index 00000000000..727be4f3b28 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications.md @@ -0,0 +1,67 @@ +# GET /cluster/notifications + +Index for notification-related API endpoints. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints.md new file mode 100644 index 00000000000..a4f95a69449 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints.md @@ -0,0 +1,67 @@ +# GET /cluster/notifications/endpoints + +Index for all available endpoint types. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_gotify.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_gotify.md new file mode 100644 index 00000000000..b2c2221275c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_gotify.md @@ -0,0 +1,140 @@ +# GET /cluster/notifications/endpoints/gotify + +Returns a list of all gotify endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_gotify_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_gotify_name.md new file mode 100644 index 00000000000..b134625f14a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_gotify_name.md @@ -0,0 +1,146 @@ +# GET /cluster/notifications/endpoints/gotify/{name} + +Return a specific gotify endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the endpoint. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_sendmail.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_sendmail.md new file mode 100644 index 00000000000..43667b5f34e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_sendmail.md @@ -0,0 +1,208 @@ +# GET /cluster/notifications/endpoints/sendmail + +Returns a list of all sendmail endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_sendmail_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_sendmail_name.md new file mode 100644 index 00000000000..90f4175c299 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_sendmail_name.md @@ -0,0 +1,193 @@ +# GET /cluster/notifications/endpoints/sendmail/{name} + +Return a specific sendmail endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_smtp.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_smtp.md new file mode 100644 index 00000000000..3105f55a280 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_smtp.md @@ -0,0 +1,256 @@ +# GET /cluster/notifications/endpoints/smtp + +Returns a list of all smtp endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_smtp_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_smtp_name.md new file mode 100644 index 00000000000..b37f2d46a04 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_smtp_name.md @@ -0,0 +1,241 @@ +# GET /cluster/notifications/endpoints/smtp/{name} + +Return a specific smtp endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_webhook.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_webhook.md new file mode 100644 index 00000000000..bd25cde682b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_webhook.md @@ -0,0 +1,200 @@ +# GET /cluster/notifications/endpoints/webhook + +Returns a list of all webhook endpoints + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_webhook_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_webhook_name.md new file mode 100644 index 00000000000..8dad555e982 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_endpoints_webhook_name.md @@ -0,0 +1,206 @@ +# GET /cluster/notifications/endpoints/webhook/{name} + +Return a specific webhook endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the endpoint. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matcher_field_values.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matcher_field_values.md new file mode 100644 index 00000000000..37947b6613d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matcher_field_values.md @@ -0,0 +1,116 @@ +# GET /cluster/notifications/matcher-field-values + +Returns known notification metadata fields and their known values + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matcher_fields.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matcher_fields.md new file mode 100644 index 00000000000..02de6c18666 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matcher_fields.md @@ -0,0 +1,110 @@ +# GET /cluster/notifications/matcher-fields + +Returns known notification metadata fields + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "name": { + "description": "Name of the field.", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matchers.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matchers.md new file mode 100644 index 00000000000..55124c38acf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matchers.md @@ -0,0 +1,262 @@ +# GET /cluster/notifications/matchers + +Returns a list of all matchers + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matchers_name.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matchers_name.md new file mode 100644 index 00000000000..609270d248c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_matchers_name.md @@ -0,0 +1,233 @@ +# GET /cluster/notifications/matchers/{name} + +Return a specific matcher + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_notifications_targets.md b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_targets.md new file mode 100644 index 00000000000..48ef09c0dcf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_notifications_targets.md @@ -0,0 +1,186 @@ +# GET /cluster/notifications/targets + +Returns a list of all entities that can be used as notification targets. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_options.md b/docs/pve-api/markdown/endpoints/GET_cluster_options.md new file mode 100644 index 00000000000..42ebee9d476 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_options.md @@ -0,0 +1,61 @@ +# GET /cluster/options + +Get datacenter options. Without 'Sys.Audit' on '/' not all options are returned. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_qemu.md b/docs/pve-api/markdown/endpoints/GET_cluster_qemu.md new file mode 100644 index 00000000000..557864c72c6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_qemu.md @@ -0,0 +1,67 @@ +# GET /cluster/qemu + +Cluster-wide QEMU index + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_qemu_cpu_flags.md b/docs/pve-api/markdown/endpoints/GET_cluster_qemu_cpu_flags.md new file mode 100644 index 00000000000..843586838b8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_qemu_cpu_flags.md @@ -0,0 +1,159 @@ +# GET /cluster/qemu/cpu-flags + +List of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| accel | string | no | Acceleration type to check node compatibility for. | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/nodes", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/mapping/cpu", + [ + "Mapping.Audit", + "Mapping.Use", + "Mapping.Modify" + ], + "any", + 1 + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_qemu_custom_cpu_models.md b/docs/pve-api/markdown/endpoints/GET_cluster_qemu_custom_cpu_models.md new file mode 100644 index 00000000000..2eb730a5048 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_qemu_custom_cpu_models.md @@ -0,0 +1,419 @@ +# GET /cluster/qemu/custom-cpu-models + +List all custom CPU model definitions visible to the user. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only lists entries where the user has 'Mapping.Modify', 'Mapping.Use' or 'Mapping.Audit' permissions on '/mapping/cpu/'.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_qemu_custom_cpu_models_cputype.md b/docs/pve-api/markdown/endpoints/GET_cluster_qemu_custom_cpu_models_cputype.md new file mode 100644 index 00000000000..8e71d3ad19a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_qemu_custom_cpu_models_cputype.md @@ -0,0 +1,454 @@ +# GET /cluster/qemu/custom-cpu-models/{cputype} + +Retrieve details about a specific custom CPU model. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | Name of the CPU model to query. The 'custom-' prefix is optional. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Use" + ] + ], + [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_replication.md b/docs/pve-api/markdown/endpoints/GET_cluster_replication.md new file mode 100644 index 00000000000..f05a5215492 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_replication.md @@ -0,0 +1,205 @@ +# GET /cluster/replication + +List replication jobs. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Will only return replication jobs for which the calling user has VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_replication_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_replication_id.md new file mode 100644 index 00000000000..694740c9e80 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_replication_id.md @@ -0,0 +1,209 @@ +# GET /cluster/replication/{id} + +Read replication job configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_resources.md b/docs/pve-api/markdown/endpoints/GET_cluster_resources.md new file mode 100644 index 00000000000..71caca716f1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_resources.md @@ -0,0 +1,506 @@ +# GET /cluster/resources + +Resources index (cluster wide). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Resource type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn.md new file mode 100644 index 00000000000..9fc8d75411e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn.md @@ -0,0 +1,87 @@ +# GET /cluster/sdn + +Directory index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_controllers.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_controllers.md new file mode 100644 index 00000000000..7d2a6a3c0ef --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_controllers.md @@ -0,0 +1,476 @@ +# GET /cluster/sdn/controllers + +SDN controllers index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | +| type | string | no | Only list sdn controllers of specific type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/controllers/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_controllers_controller.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_controllers_controller.md new file mode 100644 index 00000000000..67d888ba29f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_controllers_controller.md @@ -0,0 +1,463 @@ +# GET /cluster/sdn/controllers/{controller} + +Read sdn controller configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers/{controller}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dns.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dns.md new file mode 100644 index 00000000000..a2908516830 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dns.md @@ -0,0 +1,95 @@ +# GET /cluster/sdn/dns + +SDN dns index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list sdn dns of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "dns": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{dns}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/dns/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dns_dns.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dns_dns.md new file mode 100644 index 00000000000..1b713a9215b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dns_dns.md @@ -0,0 +1,69 @@ +# GET /cluster/sdn/dns/{dns} + +Read sdn dns configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns/{dns}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dry_run.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dry_run.md new file mode 100644 index 00000000000..4ac867b0eaa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_dry_run.md @@ -0,0 +1,95 @@ +# GET /cluster/sdn/dry-run + +Dry-run the SDN apply action and return the difference between the current configuration and the pending configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics.md new file mode 100644 index 00000000000..741ece92d02 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics.md @@ -0,0 +1,85 @@ +# GET /cluster/sdn/fabrics + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_all.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_all.md new file mode 100644 index 00000000000..f169e7ca3e0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_all.md @@ -0,0 +1,875 @@ +# GET /cluster/sdn/fabrics/all + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + }, + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_fabric.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_fabric.md new file mode 100644 index 00000000000..d99cf12a74c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_fabric.md @@ -0,0 +1,399 @@ +# GET /cluster/sdn/fabrics/fabric + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/fabrics/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_fabric_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_fabric_id.md new file mode 100644 index 00000000000..b47ed2e8bf2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_fabric_id.md @@ -0,0 +1,392 @@ +# GET /cluster/sdn/fabrics/fabric/{id} + +Update a fabric + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node.md new file mode 100644 index 00000000000..c54e40934fb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node.md @@ -0,0 +1,549 @@ +# GET /cluster/sdn/fabrics/node + +SDN Fabrics Index + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + }, + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node_fabric_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node_fabric_id.md new file mode 100644 index 00000000000..8105f9be581 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node_fabric_id.md @@ -0,0 +1,571 @@ +# GET /cluster/sdn/fabrics/node/{fabric_id} + +SDN Fabrics Index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + }, + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit" + ] + ], + "description": "Only returns nodes where you have 'Sys.Audit' or 'Sys.Modify' permissions." +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node_fabric_id_node_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node_fabric_id_node_id.md new file mode 100644 index 00000000000..3cb944000fa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_fabrics_node_fabric_id_node_id.md @@ -0,0 +1,573 @@ +# GET /cluster/sdn/fabrics/node/{fabric_id}/{node_id} + +Get a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | +| node_id | string | yes | Identifier for nodes in an SDN fabric | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" + } + }, + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams.md new file mode 100644 index 00000000000..3fb75705bc4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams.md @@ -0,0 +1,97 @@ +# GET /cluster/sdn/ipams + +SDN ipams index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list sdn ipams of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "ipam": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{ipam}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/ipams/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams_ipam.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams_ipam.md new file mode 100644 index 00000000000..a7372108029 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams_ipam.md @@ -0,0 +1,69 @@ +# GET /cluster/sdn/ipams/{ipam} + +Read sdn ipam configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams/{ipam}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams_ipam_status.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams_ipam_status.md new file mode 100644 index 00000000000..46ef17e1d50 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_ipams_ipam_status.md @@ -0,0 +1,60 @@ +# GET /cluster/sdn/ipams/{ipam}/status + +List PVE IPAM Entries + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists.md new file mode 100644 index 00000000000..90c6f5dcce7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists.md @@ -0,0 +1,92 @@ +# GET /cluster/sdn/prefix-lists + +List Prefix Lists + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | +| verbose | boolean | no | If 0, only returns id - otherwise returns all properties. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only returns prefix list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id.md new file mode 100644 index 00000000000..5579fc7675d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id.md @@ -0,0 +1,68 @@ +# GET /cluster/sdn/prefix-lists/{id} + +Get Prefix List + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id_entries.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id_entries.md new file mode 100644 index 00000000000..d28bf9cf988 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id_entries.md @@ -0,0 +1,88 @@ +# GET /cluster/sdn/prefix-lists/{id}/entries + +List Prefix List Entries + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{seq}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id_entries_url_seq.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id_entries_url_seq.md new file mode 100644 index 00000000000..0e00605f080 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_prefix_lists_id_entries_url_seq.md @@ -0,0 +1,68 @@ +# GET /cluster/sdn/prefix-lists/{id}/entries/{url_seq} + +Get Prefix List Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps.md new file mode 100644 index 00000000000..b89183ac26a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps.md @@ -0,0 +1,90 @@ +# GET /cluster/sdn/route-maps + +List Route Maps + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only returns route maps where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries.md new file mode 100644 index 00000000000..2b3537c5add --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries.md @@ -0,0 +1,319 @@ +# GET /cluster/sdn/route-maps/entries + +Lists all route map entries. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only returns route map entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries_route_map_id.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries_route_map_id.md new file mode 100644 index 00000000000..47910396fbb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries_route_map_id.md @@ -0,0 +1,343 @@ +# GET /cluster/sdn/route-maps/entries/{route-map-id} + +List all entries for a given Route Map + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries_route_map_id_entry_order.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries_route_map_id_entry_order.md new file mode 100644 index 00000000000..6cd9235b53a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_route_maps_entries_route_map_id_entry_order.md @@ -0,0 +1,318 @@ +# GET /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order} + +Get Route Map Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Audit", + "SDN.Allocate" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets.md new file mode 100644 index 00000000000..532d8fa2d7d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets.md @@ -0,0 +1,274 @@ +# GET /cluster/sdn/vnets + +SDN vnets index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet.md new file mode 100644 index 00000000000..79c1f11aac7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet.md @@ -0,0 +1,263 @@ +# GET /cluster/sdn/vnets/{vnet} + +Read sdn vnet configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall.md new file mode 100644 index 00000000000..8c52584fbc3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall.md @@ -0,0 +1,71 @@ +# GET /cluster/sdn/vnets/{vnet}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_options.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_options.md new file mode 100644 index 00000000000..1d1eac19eba --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_options.md @@ -0,0 +1,126 @@ +# GET /cluster/sdn/vnets/{vnet}/firewall/options + +Get vnet firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules.md new file mode 100644 index 00000000000..1c40b091754 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules.md @@ -0,0 +1,249 @@ +# GET /cluster/sdn/vnets/{vnet}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules_pos.md new file mode 100644 index 00000000000..8844857587b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules_pos.md @@ -0,0 +1,239 @@ +# GET /cluster/sdn/vnets/{vnet}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Audit or SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_subnets.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_subnets.md new file mode 100644 index 00000000000..f1d4620ae57 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_subnets.md @@ -0,0 +1,95 @@ +# GET /cluster/sdn/vnets/{vnet}/subnets + +SDN subnets index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{subnet}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_subnets_subnet.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_subnets_subnet.md new file mode 100644 index 00000000000..8c355696bca --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_vnets_vnet_subnets_subnet.md @@ -0,0 +1,82 @@ +# GET /cluster/sdn/vnets/{vnet}/subnets/{subnet} + +Read sdn subnet configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_zones.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_zones.md new file mode 100644 index 00000000000..4c86a757098 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_zones.md @@ -0,0 +1,738 @@ +# GET /cluster/sdn/zones + +SDN zones index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | +| type | string | no | Only list SDN zones of specific type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_sdn_zones_zone.md b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_zones_zone.md new file mode 100644 index 00000000000..17d57cd5d34 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_sdn_zones_zone.md @@ -0,0 +1,723 @@ +# GET /cluster/sdn/zones/{zone} + +Read sdn zone configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pending | boolean | no | Display pending config. | +| running | boolean | no | Display running config. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_status.md b/docs/pve-api/markdown/endpoints/GET_cluster_status.md new file mode 100644 index 00000000000..5aa4fc2e46c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_status.md @@ -0,0 +1,178 @@ +# GET /cluster/status + +Get cluster status information. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_cluster_tasks.md b/docs/pve-api/markdown/endpoints/GET_cluster_tasks.md new file mode 100644 index 00000000000..035a56c9026 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_cluster_tasks.md @@ -0,0 +1,63 @@ +# GET /cluster/tasks + +List recent tasks (cluster wide). + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "upid": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes.md b/docs/pve-api/markdown/endpoints/GET_nodes.md new file mode 100644 index 00000000000..85969a3ccf4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes.md @@ -0,0 +1,175 @@ +# GET /nodes + +Cluster node index. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node.md b/docs/pve-api/markdown/endpoints/GET_nodes_node.md new file mode 100644 index 00000000000..e3c86b9d038 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node.md @@ -0,0 +1,77 @@ +# GET /nodes/{node} + +Node index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_aplinfo.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_aplinfo.md new file mode 100644 index 00000000000..39dffa7d4e2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_aplinfo.md @@ -0,0 +1,66 @@ +# GET /nodes/{node}/aplinfo + +Get list of appliances. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_apt.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt.md new file mode 100644 index 00000000000..25db98a8af3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt.md @@ -0,0 +1,85 @@ +# GET /nodes/{node}/apt + +Directory index for apt (Advanced Package Tool). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_changelog.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_changelog.md new file mode 100644 index 00000000000..ecb85d453d5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_changelog.md @@ -0,0 +1,84 @@ +# GET /nodes/{node}/apt/changelog + +Get package changelogs. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Package name. | +| version | string | no | Package version. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_repositories.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_repositories.md new file mode 100644 index 00000000000..a5e586c88a4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_repositories.md @@ -0,0 +1,434 @@ +# GET /nodes/{node}/apt/repositories + +Get APT repository information. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_update.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_update.md new file mode 100644 index 00000000000..c9a92765cc2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_update.md @@ -0,0 +1,183 @@ +# GET /nodes/{node}/apt/update + +List available updates. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_versions.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_versions.md new file mode 100644 index 00000000000..11b638f86ae --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_apt_versions.md @@ -0,0 +1,226 @@ +# GET /nodes/{node}/apt/versions + +Get package information for important Proxmox packages. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities.md new file mode 100644 index 00000000000..8306995b463 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities.md @@ -0,0 +1,78 @@ +# GET /nodes/{node}/capabilities + +Node capabilities index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu.md new file mode 100644 index 00000000000..e12f5e21c4d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu.md @@ -0,0 +1,78 @@ +# GET /nodes/{node}/capabilities/qemu + +QEMU capabilities index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_cpu.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_cpu.md new file mode 100644 index 00000000000..057413ab2dd --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_cpu.md @@ -0,0 +1,126 @@ +# GET /nodes/{node}/capabilities/qemu/cpu + +List all custom and default CPU models. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_cpu_flags.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_cpu_flags.md new file mode 100644 index 00000000000..4b38407916c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_cpu_flags.md @@ -0,0 +1,127 @@ +# GET /nodes/{node}/capabilities/qemu/cpu-flags + +List of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| accel | string | no | Acceleration type to check node compatibility for. | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_machines.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_machines.md new file mode 100644 index 00000000000..4de67472ba8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_machines.md @@ -0,0 +1,123 @@ +# GET /nodes/{node}/capabilities/qemu/machines + +Get available QEMU/KVM machine types. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_migration.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_migration.md new file mode 100644 index 00000000000..33f471a34ce --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_capabilities_qemu_migration.md @@ -0,0 +1,84 @@ +# GET /nodes/{node}/capabilities/qemu/migration + +Get node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph.md new file mode 100644 index 00000000000..ca81c6da4a6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/ceph + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg.md new file mode 100644 index 00000000000..71a3f895b94 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg.md @@ -0,0 +1,77 @@ +# GET /nodes/{node}/ceph/cfg + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_db.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_db.md new file mode 100644 index 00000000000..c5f9c890811 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_db.md @@ -0,0 +1,147 @@ +# GET /nodes/{node}/ceph/cfg/db + +Get the Ceph configuration database. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_raw.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_raw.md new file mode 100644 index 00000000000..aa3221056f4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_raw.md @@ -0,0 +1,76 @@ +# GET /nodes/{node}/ceph/cfg/raw + +Get the Ceph configuration file. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_value.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_value.md new file mode 100644 index 00000000000..66e369054bc --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cfg_value.md @@ -0,0 +1,82 @@ +# GET /nodes/{node}/ceph/cfg/value + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| config-keys | string | yes | List of
: items separated by semicolon, comma or space. | + +## Returns + +```json +{ + "description": "Two-level map of {section} -> {key} -> value. Underscores in section and key names are normalised to hyphens.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cmd_safety.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cmd_safety.md new file mode 100644 index 00000000000..bfea47c6835 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_cmd_safety.md @@ -0,0 +1,121 @@ +# GET /nodes/{node}/ceph/cmd-safety + +Heuristical check if it is safe to perform an action. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Action to check | +| id | string | yes | ID of the service | +| service | string | yes | Service type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_crush.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_crush.md new file mode 100644 index 00000000000..269f019e1c1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_crush.md @@ -0,0 +1,77 @@ +# GET /nodes/{node}/ceph/crush + +Get OSD crush map + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_fs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_fs.md new file mode 100644 index 00000000000..89233810575 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_fs.md @@ -0,0 +1,171 @@ +# GET /nodes/{node}/ceph/fs + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_log.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_log.md new file mode 100644 index 00000000000..fe9710c8ec7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_log.md @@ -0,0 +1,114 @@ +# GET /nodes/{node}/ceph/log + +Read ceph log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted. | +| start | integer | no | Offset of the first log line to return (0-based). | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Log-file line number (1-based).", + "type": "integer" + }, + "t": { + "description": "Log line text.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mds.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mds.md new file mode 100644 index 00000000000..c66dfee361b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mds.md @@ -0,0 +1,205 @@ +# GET /nodes/{node}/ceph/mds + +MDS directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mgr.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mgr.md new file mode 100644 index 00000000000..b71baa76f21 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mgr.md @@ -0,0 +1,175 @@ +# GET /nodes/{node}/ceph/mgr + +MGR directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mon.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mon.md new file mode 100644 index 00000000000..bd6cf74d2d0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_mon.md @@ -0,0 +1,197 @@ +# GET /nodes/{node}/ceph/mon + +Get Ceph monitor list. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd.md new file mode 100644 index 00000000000..ec82c22ea13 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd.md @@ -0,0 +1,103 @@ +# GET /nodes/{node}/ceph/osd + +Get Ceph osd list/tree. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid.md new file mode 100644 index 00000000000..932285ac0fb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid.md @@ -0,0 +1,83 @@ +# GET /nodes/{node}/ceph/osd/{osdid} + +OSD index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid_lv_info.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid_lv_info.md new file mode 100644 index 00000000000..a363a961cd8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid_lv_info.md @@ -0,0 +1,146 @@ +# GET /nodes/{node}/ceph/osd/{osdid}/lv-info + +Get OSD volume details + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | OSD device type | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid_metadata.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid_metadata.md new file mode 100644 index 00000000000..6415ac95b85 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_osd_osdid_metadata.md @@ -0,0 +1,271 @@ +# GET /nodes/{node}/ceph/osd/{osdid}/metadata + +Get OSD details + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool.md new file mode 100644 index 00000000000..947b9930c10 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool.md @@ -0,0 +1,301 @@ +# GET /nodes/{node}/ceph/pool + +List all pools and their settings (which are settable by the POST/PUT endpoints). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool_name.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool_name.md new file mode 100644 index 00000000000..5b0e0af750a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool_name.md @@ -0,0 +1,101 @@ +# GET /nodes/{node}/ceph/pool/{name} + +Pool index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool_name_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool_name_status.md new file mode 100644 index 00000000000..c03b83d9960 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_pool_name_status.md @@ -0,0 +1,416 @@ +# GET /nodes/{node}/ceph/pool/{name}/status + +Show the current pool status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| verbose | boolean | no | If enabled, will display additional data(eg. statistics). | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_rules.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_rules.md new file mode 100644 index 00000000000..b48abe941f9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_rules.md @@ -0,0 +1,107 @@ +# GET /nodes/{node}/ceph/rules + +List ceph rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "name": { + "description": "Name of the CRUSH rule.", + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_status.md new file mode 100644 index 00000000000..039b7eb4743 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_ceph_status.md @@ -0,0 +1,77 @@ +# GET /nodes/{node}/ceph/status + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Datastore.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates.md new file mode 100644 index 00000000000..cec7fcb8d5c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates.md @@ -0,0 +1,77 @@ +# GET /nodes/{node}/certificates + +Node index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates_acme.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates_acme.md new file mode 100644 index 00000000000..84d89681d52 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates_acme.md @@ -0,0 +1,77 @@ +# GET /nodes/{node}/certificates/acme + +ACME index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates_info.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates_info.md new file mode 100644 index 00000000000..59fbf689a7b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_certificates_info.md @@ -0,0 +1,182 @@ +# GET /nodes/{node}/certificates/info + +Get information about node's certificates. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_config.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_config.md new file mode 100644 index 00000000000..8d65ce037ea --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_config.md @@ -0,0 +1,366 @@ +# GET /nodes/{node}/config + +Get node configuration options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| property | string | no | Return only a specific property from the node configuration. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks.md new file mode 100644 index 00000000000..06f01cc2365 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks.md @@ -0,0 +1,78 @@ +# GET /nodes/{node}/disks + +Node index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_directory.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_directory.md new file mode 100644 index 00000000000..08133ffda01 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_directory.md @@ -0,0 +1,121 @@ +# GET /nodes/{node}/disks/directory + +PVE Managed Directory storages. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_list.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_list.md new file mode 100644 index 00000000000..16d09b28065 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_list.md @@ -0,0 +1,230 @@ +# GET /nodes/{node}/disks/list + +List local disks. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| include-partitions | boolean | no | Also include partitions. | +| skipsmart | boolean | no | Skip smart checks. | +| type | string | no | Only list specific types of disks. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_lvm.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_lvm.md new file mode 100644 index 00000000000..6f049eb48d0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_lvm.md @@ -0,0 +1,177 @@ +# GET /nodes/{node}/disks/lvm + +List LVM Volume Groups + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_lvmthin.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_lvmthin.md new file mode 100644 index 00000000000..0b8d0100c09 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_lvmthin.md @@ -0,0 +1,129 @@ +# GET /nodes/{node}/disks/lvmthin + +List LVM thinpools + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_smart.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_smart.md new file mode 100644 index 00000000000..9819eb795c4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_smart.md @@ -0,0 +1,119 @@ +# GET /nodes/{node}/disks/smart + +Get SMART Health of a disk. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | Block device name | +| healthonly | boolean | no | If true returns only the health status | + +## Returns + +```json +{ + "properties": { + "attributes": { + "optional": 1, + "type": "array" + }, + "health": { + "type": "string" + }, + "text": { + "optional": 1, + "type": "string" + }, + "type": { + "optional": 1, + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_zfs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_zfs.md new file mode 100644 index 00000000000..f08bc9730a8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_zfs.md @@ -0,0 +1,149 @@ +# GET /nodes/{node}/disks/zfs + +List Zpools. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_zfs_name.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_zfs_name.md new file mode 100644 index 00000000000..0d0a32dfac5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_disks_zfs_name.md @@ -0,0 +1,205 @@ +# GET /nodes/{node}/disks/zfs/{name} + +Get details about a zpool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The storage identifier. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_dns.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_dns.md new file mode 100644 index 00000000000..0907a9418bb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_dns.md @@ -0,0 +1,116 @@ +# GET /nodes/{node}/dns + +Read DNS settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall.md new file mode 100644 index 00000000000..def9382090f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall.md @@ -0,0 +1,77 @@ +# GET /nodes/{node}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_log.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_log.md new file mode 100644 index 00000000000..d71dd9d84c2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_log.md @@ -0,0 +1,128 @@ +# GET /nodes/{node}/firewall/log + +Read firewall log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| since | integer | no | Display log since this UNIX epoch. | +| start | integer | no | | +| until | integer | no | Display log until this UNIX epoch. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_options.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_options.md new file mode 100644 index 00000000000..8f956ab2596 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_options.md @@ -0,0 +1,410 @@ +# GET /nodes/{node}/firewall/options + +Get host firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_rules.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_rules.md new file mode 100644 index 00000000000..0b4f3e6c5e2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_rules.md @@ -0,0 +1,258 @@ +# GET /nodes/{node}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_rules_pos.md new file mode 100644 index 00000000000..d5e2e75d5c7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_firewall_rules_pos.md @@ -0,0 +1,248 @@ +# GET /nodes/{node}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware.md new file mode 100644 index 00000000000..091fceeaa03 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware.md @@ -0,0 +1,85 @@ +# GET /nodes/{node}/hardware + +Index of hardware types + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "type": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{type}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci.md new file mode 100644 index 00000000000..49f3af46814 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci.md @@ -0,0 +1,219 @@ +# GET /nodes/{node}/hardware/pci + +List local PCI devices. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pci-class-blacklist | string | no | A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b). | +| verbose | boolean | no | If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping.md new file mode 100644 index 00000000000..a195a0c4832 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping.md @@ -0,0 +1,90 @@ +# GET /nodes/{node}/hardware/pci/{pci-id-or-mapping} + +Index of available pci methods + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pci-id-or-mapping | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "method": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{method}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping_mdev.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping_mdev.md new file mode 100644 index 00000000000..44746966d37 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping_mdev.md @@ -0,0 +1,127 @@ +# GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev + +List mediated device types for given PCI device. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pci-id-or-mapping | string | yes | The PCI ID or mapping to list the mdev types for. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_usb.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_usb.md new file mode 100644 index 00000000000..19626e72bda --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_hardware_usb.md @@ -0,0 +1,161 @@ +# GET /nodes/{node}/hardware/usb + +List local USB devices. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_hosts.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_hosts.md new file mode 100644 index 00000000000..b3f55d5b0ad --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_hosts.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/hosts + +Get the content of /etc/hosts. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_journal.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_journal.md new file mode 100644 index 00000000000..563c1fa7f24 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_journal.md @@ -0,0 +1,117 @@ +# GET /nodes/{node}/journal + +Read Journal + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| endcursor | string | no | End before the given Cursor. Conflicts with 'until' | +| lastentries | integer | no | Limit to the last X lines. Conflicts with a range. | +| since | integer | no | Display all log since this UNIX epoch. Conflicts with 'startcursor'. | +| startcursor | string | no | Start after the given Cursor. Conflicts with 'since' | +| until | integer | no | Display all log until this UNIX epoch. Conflicts with 'endcursor'. | + +## Returns + +```json +{ + "items": { + "type": "string" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc.md new file mode 100644 index 00000000000..31142d2bfff --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc.md @@ -0,0 +1,347 @@ +# GET /nodes/{node}/lxc + +LXC container index (per node). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list CTs where you have VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid.md new file mode 100644 index 00000000000..b1114a739eb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/lxc/{vmid} + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_config.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_config.md new file mode 100644 index 00000000000..4a929a6a495 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_config.md @@ -0,0 +1,1247 @@ +# GET /nodes/{node}/lxc/{vmid}/config + +Get container configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| current | boolean | no | Get current values (instead of pending values). | +| snapshot | string | no | Fetch config values from given snapshot. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_feature.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_feature.md new file mode 100644 index 00000000000..e78f7a94ef6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_feature.md @@ -0,0 +1,110 @@ +# GET /nodes/{node}/lxc/{vmid}/feature + +Check if feature for virtual machine is available. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| feature | string | yes | Feature to check. | +| snapname | string | no | The name of the snapshot. | + +## Returns + +```json +{ + "properties": { + "hasFeature": { + "type": "boolean" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall.md new file mode 100644 index 00000000000..c6c7cbb43c0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall.md @@ -0,0 +1,86 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_aliases.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_aliases.md new file mode 100644 index 00000000000..197137a62b6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_aliases.md @@ -0,0 +1,132 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/aliases + +List aliases + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_aliases_name.md new file mode 100644 index 00000000000..765e7ac79f7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_aliases_name.md @@ -0,0 +1,86 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/aliases/{name} + +Read alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset.md new file mode 100644 index 00000000000..ce93f99749e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset.md @@ -0,0 +1,134 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/ipset + +List IPSets + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name.md new file mode 100644 index 00000000000..a185daabc18 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name.md @@ -0,0 +1,142 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name} + +List IPSet content + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..581ac4adb76 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md @@ -0,0 +1,94 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr} + +Read IP or Network settings from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_log.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_log.md new file mode 100644 index 00000000000..8de4d3fe6ae --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_log.md @@ -0,0 +1,137 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/log + +Read firewall log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| since | integer | no | Display log since this UNIX epoch. | +| start | integer | no | | +| until | integer | no | Display log until this UNIX epoch. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_options.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_options.md new file mode 100644 index 00000000000..21d887f6dac --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_options.md @@ -0,0 +1,255 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/options + +Get VM firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_refs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_refs.md new file mode 100644 index 00000000000..205e8ea077b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_refs.md @@ -0,0 +1,139 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/refs + +Lists possible IPSet/Alias reference which are allowed in source/dest properties. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list references of specified type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_rules.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_rules.md new file mode 100644 index 00000000000..c1d3eaddef0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_rules.md @@ -0,0 +1,267 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_rules_pos.md new file mode 100644 index 00000000000..9002b4c68d7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_firewall_rules_pos.md @@ -0,0 +1,257 @@ +# GET /nodes/{node}/lxc/{vmid}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_interfaces.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_interfaces.md new file mode 100644 index 00000000000..a8c7b87641e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_interfaces.md @@ -0,0 +1,190 @@ +# GET /nodes/{node}/lxc/{vmid}/interfaces + +Get IP addresses of the specified container interface. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_migrate.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_migrate.md new file mode 100644 index 00000000000..d3a62cf6908 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_migrate.md @@ -0,0 +1,197 @@ +# GET /nodes/{node}/lxc/{vmid}/migrate + +Get preconditions for migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | no | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_mtunnelwebsocket.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_mtunnelwebsocket.md new file mode 100644 index 00000000000..baae52a4e98 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_mtunnelwebsocket.md @@ -0,0 +1,101 @@ +# GET /nodes/{node}/lxc/{vmid}/mtunnelwebsocket + +Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| socket | string | yes | unix socket to forward to | +| ticket | string | yes | ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command | + +## Returns + +```json +{ + "properties": { + "port": { + "optional": 1, + "type": "string" + }, + "socket": { + "optional": 1, + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_pending.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_pending.md new file mode 100644 index 00000000000..9995f76a765 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_pending.md @@ -0,0 +1,131 @@ +# GET /nodes/{node}/lxc/{vmid}/pending + +Get container configuration, including pending changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_rrd.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_rrd.md new file mode 100644 index 00000000000..c94e50d8da4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_rrd.md @@ -0,0 +1,119 @@ +# GET /nodes/{node}/lxc/{vmid}/rrd + +Read VM RRD statistics (returns PNG) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_rrddata.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_rrddata.md new file mode 100644 index 00000000000..70193f1b580 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_rrddata.md @@ -0,0 +1,110 @@ +# GET /nodes/{node}/lxc/{vmid}/rrddata + +Read VM RRD statistics + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot.md new file mode 100644 index 00000000000..aa6f3da2857 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot.md @@ -0,0 +1,140 @@ +# GET /nodes/{node}/lxc/{vmid}/snapshot + +List all snapshots. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname.md new file mode 100644 index 00000000000..5cfc0915446 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname.md @@ -0,0 +1,94 @@ +# GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname} + +snapshot_cmd_idx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{cmd}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname_config.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname_config.md new file mode 100644 index 00000000000..939aafe4f21 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname_config.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config + +Get snapshot configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_status.md new file mode 100644 index 00000000000..7640a586dce --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_status.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/lxc/{vmid}/status + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_status_current.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_status_current.md new file mode 100644 index 00000000000..b1914af73b1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_status_current.md @@ -0,0 +1,356 @@ +# GET /nodes/{node}/lxc/{vmid}/status/current + +Get virtual machine status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_vncwebsocket.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_vncwebsocket.md new file mode 100644 index 00000000000..0ea2bbd241a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_lxc_vmid_vncwebsocket.md @@ -0,0 +1,106 @@ +# GET /nodes/{node}/lxc/{vmid}/vncwebsocket + +Opens a websocket for VNC traffic. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | Port number returned by previous vncproxy call. | +| vncticket | string | yes | Ticket from previous call to vncproxy. | + +## Returns + +```json +{ + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_netstat.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_netstat.md new file mode 100644 index 00000000000..45850e52f3c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_netstat.md @@ -0,0 +1,78 @@ +# GET /nodes/{node}/netstat + +Read tap/vm network device interface counters + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_network.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_network.md new file mode 100644 index 00000000000..7d04e4e00da --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_network.md @@ -0,0 +1,771 @@ +# GET /nodes/{node}/network + +List available networks + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list specific interface types. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_network_iface.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_network_iface.md new file mode 100644 index 00000000000..f3391c3ac90 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_network_iface.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/network/{iface} + +Read network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "properties": { + "method": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu.md new file mode 100644 index 00000000000..b0ab74327e4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu.md @@ -0,0 +1,401 @@ +# GET /nodes/{node}/qemu + +Virtual machine index (per node). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| full | boolean | no | Determine the full status of active VMs. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list VMs where you have VM.Audit permissions on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid.md new file mode 100644 index 00000000000..ad1b6ba9470 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/qemu/{vmid} + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent.md new file mode 100644 index 00000000000..fc90b7f3012 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent.md @@ -0,0 +1,89 @@ +# GET /nodes/{node}/qemu/{vmid}/agent + +QEMU Guest Agent command index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns the list of QEMU Guest Agent commands", + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_exec_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_exec_status.md new file mode 100644 index 00000000000..aa48ee55c59 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_exec_status.md @@ -0,0 +1,159 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/exec-status + +Gets the status of the given pid started by the guest-agent + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pid | integer | yes | The PID to query | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_file_read.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_file_read.md new file mode 100644 index 00000000000..92558a29e32 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_file_read.md @@ -0,0 +1,144 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/file-read + +Reads the given file via guest agent. Is limited to 16777216 bytes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| file | string | yes | The path to the file | +| count | integer | no | Number of bytes to read. | +| decode | boolean | no | 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. | +| offset | integer | no | Offset to start reading at | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileRead", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_fsinfo.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_fsinfo.md new file mode 100644 index 00000000000..836a23068ec --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_fsinfo.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-fsinfo + +Execute get-fsinfo. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_host_name.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_host_name.md new file mode 100644 index 00000000000..dfc56187088 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_host_name.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-host-name + +Execute get-host-name. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_block_info.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_block_info.md new file mode 100644 index 00000000000..e98ec592491 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_block_info.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-memory-block-info + +Execute get-memory-block-info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_blocks.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_blocks.md new file mode 100644 index 00000000000..dd33dcd79b3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_blocks.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-memory-blocks + +Execute get-memory-blocks. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_osinfo.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_osinfo.md new file mode 100644 index 00000000000..98827601ec2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_osinfo.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-osinfo + +Execute get-osinfo. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_time.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_time.md new file mode 100644 index 00000000000..1f9132bb932 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_time.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-time + +Execute get-time. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_timezone.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_timezone.md new file mode 100644 index 00000000000..4a1e24014d0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_timezone.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-timezone + +Execute get-timezone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_users.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_users.md new file mode 100644 index 00000000000..4c6f95de0c0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_users.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-users + +Execute get-users. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_vcpus.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_vcpus.md new file mode 100644 index 00000000000..3abaafe3733 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_get_vcpus.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/get-vcpus + +Execute get-vcpus. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_info.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_info.md new file mode 100644 index 00000000000..804e9e32faf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_info.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/info + +Execute info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_network_get_interfaces.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_network_get_interfaces.md new file mode 100644 index 00000000000..1616a58dbf3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_agent_network_get_interfaces.md @@ -0,0 +1,88 @@ +# GET /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces + +Execute network-get-interfaces. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_cloudinit.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_cloudinit.md new file mode 100644 index 00000000000..29d4b1c1d01 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_cloudinit.md @@ -0,0 +1,131 @@ +# GET /nodes/{node}/qemu/{vmid}/cloudinit + +Get the cloudinit configuration with both current and pending values. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_cloudinit_dump.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_cloudinit_dump.md new file mode 100644 index 00000000000..341fe0412d9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_cloudinit_dump.md @@ -0,0 +1,90 @@ +# GET /nodes/{node}/qemu/{vmid}/cloudinit/dump + +Get automatically generated cloudinit config. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | Config type. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_config.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_config.md new file mode 100644 index 00000000000..f4b6f1de644 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_config.md @@ -0,0 +1,4849 @@ +# GET /nodes/{node}/qemu/{vmid}/config + +Get the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| current | boolean | no | Get current values (instead of pending values). | +| snapshot | string | no | Fetch config values from given snapshot. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_feature.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_feature.md new file mode 100644 index 00000000000..3ce23b15a26 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_feature.md @@ -0,0 +1,122 @@ +# GET /nodes/{node}/qemu/{vmid}/feature + +Check if feature for virtual machine is available. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| feature | string | yes | Feature to check. | +| snapname | string | no | The name of the snapshot. | + +## Returns + +```json +{ + "properties": { + "hasFeature": { + "type": "boolean" + }, + "nodes": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall.md new file mode 100644 index 00000000000..89035a5bf28 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall.md @@ -0,0 +1,86 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_aliases.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_aliases.md new file mode 100644 index 00000000000..fa2904c9733 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_aliases.md @@ -0,0 +1,132 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/aliases + +List aliases + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_aliases_name.md new file mode 100644 index 00000000000..7130db5c56a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_aliases_name.md @@ -0,0 +1,86 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/aliases/{name} + +Read alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset.md new file mode 100644 index 00000000000..6c2781e9f97 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset.md @@ -0,0 +1,134 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/ipset + +List IPSets + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name.md new file mode 100644 index 00000000000..885a3eb80aa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name.md @@ -0,0 +1,142 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name} + +List IPSet content + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..945cb337670 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md @@ -0,0 +1,94 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr} + +Read IP or Network settings from IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_log.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_log.md new file mode 100644 index 00000000000..7818a04dc52 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_log.md @@ -0,0 +1,137 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/log + +Read firewall log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| since | integer | no | Display log since this UNIX epoch. | +| start | integer | no | | +| until | integer | no | Display log until this UNIX epoch. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_options.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_options.md new file mode 100644 index 00000000000..6d3603f0564 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_options.md @@ -0,0 +1,255 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/options + +Get VM firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_refs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_refs.md new file mode 100644 index 00000000000..417858c6fb9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_refs.md @@ -0,0 +1,139 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/refs + +Lists possible IPSet/Alias reference which are allowed in source/dest properties. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list references of specified type. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_rules.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_rules.md new file mode 100644 index 00000000000..ab460768fc0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_rules.md @@ -0,0 +1,267 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/rules + +List rules. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_rules_pos.md new file mode 100644 index 00000000000..d23781ee371 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_firewall_rules_pos.md @@ -0,0 +1,257 @@ +# GET /nodes/{node}/qemu/{vmid}/firewall/rules/{pos} + +Get single rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_migrate.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_migrate.md new file mode 100644 index 00000000000..088e958df62 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_migrate.md @@ -0,0 +1,313 @@ +# GET /nodes/{node}/qemu/{vmid}/migrate + +Get preconditions for migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | no | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_mtunnelwebsocket.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_mtunnelwebsocket.md new file mode 100644 index 00000000000..cb28b76f660 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_mtunnelwebsocket.md @@ -0,0 +1,101 @@ +# GET /nodes/{node}/qemu/{vmid}/mtunnelwebsocket + +Migration tunnel endpoint for websocket upgrade - only for internal use by VM migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| socket | string | yes | unix socket to forward to | +| ticket | string | yes | ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command | + +## Returns + +```json +{ + "properties": { + "port": { + "optional": 1, + "type": "string" + }, + "socket": { + "optional": 1, + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_pending.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_pending.md new file mode 100644 index 00000000000..dce3a43151d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_pending.md @@ -0,0 +1,131 @@ +# GET /nodes/{node}/qemu/{vmid}/pending + +Get the virtual machine configuration with both current and pending values. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_rrd.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_rrd.md new file mode 100644 index 00000000000..a09f0d11341 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_rrd.md @@ -0,0 +1,119 @@ +# GET /nodes/{node}/qemu/{vmid}/rrd + +Read VM RRD statistics (returns PNG) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_rrddata.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_rrddata.md new file mode 100644 index 00000000000..ea444a301af --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_rrddata.md @@ -0,0 +1,110 @@ +# GET /nodes/{node}/qemu/{vmid}/rrddata + +Read VM RRD statistics + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot.md new file mode 100644 index 00000000000..c36b097c62d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot.md @@ -0,0 +1,150 @@ +# GET /nodes/{node}/qemu/{vmid}/snapshot + +List all snapshots. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname.md new file mode 100644 index 00000000000..1d36d93e070 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname.md @@ -0,0 +1,94 @@ +# GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname} + +snapshot_cmd_idx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{cmd}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname_config.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname_config.md new file mode 100644 index 00000000000..634c22eed04 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname_config.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config + +Get snapshot configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback", + "VM.Audit" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_status.md new file mode 100644 index 00000000000..d7911934f9c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_status.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/qemu/{vmid}/status + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_status_current.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_status_current.md new file mode 100644 index 00000000000..61d20a612a4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_status_current.md @@ -0,0 +1,438 @@ +# GET /nodes/{node}/qemu/{vmid}/status/current + +Get virtual machine status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_vncwebsocket.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_vncwebsocket.md new file mode 100644 index 00000000000..e51f995aefd --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_qemu_vmid_vncwebsocket.md @@ -0,0 +1,106 @@ +# GET /nodes/{node}/qemu/{vmid}/vncwebsocket + +Opens a websocket for VNC traffic. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | Port number returned by previous vncproxy call. | +| vncticket | string | yes | Ticket from previous call to vncproxy. | + +## Returns + +```json +{ + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_query_oci_repo_tags.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_query_oci_repo_tags.md new file mode 100644 index 00000000000..f25ed118dbe --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_query_oci_repo_tags.md @@ -0,0 +1,83 @@ +# GET /nodes/{node}/query-oci-repo-tags + +List all tags for an OCI repository reference. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| reference | string | yes | The reference to the repository to query tags from. | + +## Returns + +```json +{ + "items": { + "type": "string" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_query_url_metadata.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_query_url_metadata.md new file mode 100644 index 00000000000..fd4793844c1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_query_url_metadata.md @@ -0,0 +1,137 @@ +# GET /nodes/{node}/query-url-metadata + +Query metadata of an URL: file size, file name and mime type. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| url | string | yes | The URL to query the metadata from. | +| verify-certificates | boolean | no | If false, no SSL/TLS certificates will be verified. | + +## Returns + +```json +{ + "properties": { + "filename": { + "optional": 1, + "type": "string" + }, + "mimetype": { + "optional": 1, + "type": "string" + }, + "size": { + "optional": 1, + "renderer": "bytes", + "type": "integer" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_replication.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication.md new file mode 100644 index 00000000000..d3c5f02f775 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication.md @@ -0,0 +1,100 @@ +# GET /nodes/{node}/replication + +List status of all replication jobs on this node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| guest | integer | no | Only list replication jobs for this guest. | + +## Returns + +```json +{ + "items": { + "properties": { + "id": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{id}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id.md new file mode 100644 index 00000000000..9f3861bacc3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id.md @@ -0,0 +1,84 @@ +# GET /nodes/{node}/replication/{id} + +Directory index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id_log.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id_log.md new file mode 100644 index 00000000000..68d3ec82bad --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id_log.md @@ -0,0 +1,109 @@ +# GET /nodes/{node}/replication/{id}/log + +Read replication job log. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| start | integer | no | | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/, or 'Sys.Audit' on '/nodes/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id_status.md new file mode 100644 index 00000000000..bb48f582337 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_replication_id_status.md @@ -0,0 +1,68 @@ +# GET /nodes/{node}/replication/{id}/status + +Get replication job status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Audit permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_report.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_report.md new file mode 100644 index 00000000000..ad04ce8c40f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_report.md @@ -0,0 +1,71 @@ +# GET /nodes/{node}/report + +Gather various systems information about a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_rrd.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_rrd.md new file mode 100644 index 00000000000..14019dd4350 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_rrd.md @@ -0,0 +1,111 @@ +# GET /nodes/{node}/rrd + +Read node RRD statistics (returns PNG) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_rrddata.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_rrddata.md new file mode 100644 index 00000000000..de1398168fc --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_rrddata.md @@ -0,0 +1,102 @@ +# GET /nodes/{node}/rrddata + +Read node RRD statistics + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan.md new file mode 100644 index 00000000000..d187c7194ac --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan.md @@ -0,0 +1,85 @@ +# GET /nodes/{node}/scan + +Index of available scan methods + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "method": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{method}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_cifs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_cifs.md new file mode 100644 index 00000000000..b082dcaa0d6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_cifs.md @@ -0,0 +1,126 @@ +# GET /nodes/{node}/scan/cifs + +Scan remote CIFS server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| server | string | yes | The server address (name or IP). | +| domain | string | no | SMB domain (Workgroup). | +| password | string | no | User password. | +| username | string | no | User name. | + +## Returns + +```json +{ + "items": { + "properties": { + "description": { + "description": "Descriptive text from server.", + "type": "string" + }, + "share": { + "description": "The cifs share name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_iscsi.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_iscsi.md new file mode 100644 index 00000000000..1cf004e5eb3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_iscsi.md @@ -0,0 +1,105 @@ +# GET /nodes/{node}/scan/iscsi + +Scan remote iSCSI server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| portal | string | yes | The iSCSI portal (IP or DNS name with optional port). | + +## Returns + +```json +{ + "items": { + "properties": { + "portal": { + "description": "The iSCSI portal name.", + "type": "string" + }, + "target": { + "description": "The iSCSI target name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_lvm.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_lvm.md new file mode 100644 index 00000000000..e95ec011164 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_lvm.md @@ -0,0 +1,89 @@ +# GET /nodes/{node}/scan/lvm + +List local LVM volume groups. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "vg": { + "description": "The LVM logical volume group name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_lvmthin.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_lvmthin.md new file mode 100644 index 00000000000..d92bd6b2466 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_lvmthin.md @@ -0,0 +1,96 @@ +# GET /nodes/{node}/scan/lvmthin + +List local LVM Thin Pools. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vg | string | yes | | + +## Returns + +```json +{ + "items": { + "properties": { + "lv": { + "description": "The LVM Thin Pool name (LVM logical volume).", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_nfs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_nfs.md new file mode 100644 index 00000000000..b924a5a9d40 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_nfs.md @@ -0,0 +1,105 @@ +# GET /nodes/{node}/scan/nfs + +Scan remote NFS server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| server | string | yes | The server address (name or IP). | + +## Returns + +```json +{ + "items": { + "properties": { + "options": { + "description": "NFS export options.", + "type": "string" + }, + "path": { + "description": "The exported path.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_pbs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_pbs.md new file mode 100644 index 00000000000..745814e071b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_pbs.md @@ -0,0 +1,136 @@ +# GET /nodes/{node}/scan/pbs + +Scan remote Proxmox Backup Server. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | User password or API token secret. | +| server | string | yes | The server address (name or IP). | +| username | string | yes | User-name or API token-ID. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| port | integer | no | Optional port. | + +## Returns + +```json +{ + "items": { + "properties": { + "comment": { + "description": "Comment from server.", + "optional": 1, + "type": "string" + }, + "store": { + "description": "The datastore name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_zfs.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_zfs.md new file mode 100644 index 00000000000..1284c6f15fa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_scan_zfs.md @@ -0,0 +1,89 @@ +# GET /nodes/{node}/scan/zfs + +Scan zfs pool list on local node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "pool": { + "description": "ZFS pool name.", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn.md new file mode 100644 index 00000000000..31c87875872 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn.md @@ -0,0 +1,78 @@ +# GET /nodes/{node}/sdn + +SDN index. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric.md new file mode 100644 index 00000000000..4ac2889da09 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric.md @@ -0,0 +1,106 @@ +# GET /nodes/{node}/sdn/fabrics/{fabric} + +Directory index for SDN fabric status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_interfaces.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_interfaces.md new file mode 100644 index 00000000000..e620655ab3d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_interfaces.md @@ -0,0 +1,114 @@ +# GET /nodes/{node}/sdn/fabrics/{fabric}/interfaces + +Get all interfaces for a fabric. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_neighbors.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_neighbors.md new file mode 100644 index 00000000000..d03f81bcb59 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_neighbors.md @@ -0,0 +1,114 @@ +# GET /nodes/{node}/sdn/fabrics/{fabric}/neighbors + +Get all neighbors for a fabric. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_routes.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_routes.md new file mode 100644 index 00000000000..daee260c0ce --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_fabrics_fabric_routes.md @@ -0,0 +1,114 @@ +# GET /nodes/{node}/sdn/fabrics/{fabric}/routes + +Get all routes for a fabric. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric | string | yes | Identifier for SDN fabrics | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{fabric}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_vnets_vnet.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_vnets_vnet.md new file mode 100644 index 00000000000..bbbad97d00b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_vnets_vnet.md @@ -0,0 +1,95 @@ +# GET /nodes/{node}/sdn/vnets/{vnet} + +diridx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_vnets_vnet_mac_vrf.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_vnets_vnet_mac_vrf.md new file mode 100644 index 00000000000..8b1629e6e1f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_vnets_vnet_mac_vrf.md @@ -0,0 +1,111 @@ +# GET /nodes/{node}/sdn/vnets/{vnet}/mac-vrf + +Get the MAC VRF for a VNet in an EVPN zone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Audit' permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones.md new file mode 100644 index 00000000000..faf902cca22 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones.md @@ -0,0 +1,115 @@ +# GET /nodes/{node}/sdn/zones + +Get status for all zones. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'SDN.Audit'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone.md new file mode 100644 index 00000000000..2ff9441a9c4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone.md @@ -0,0 +1,105 @@ +# GET /nodes/{node}/sdn/zones/{zone} + +Directory index for SDN zone status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_bridges.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_bridges.md new file mode 100644 index 00000000000..5f976490093 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_bridges.md @@ -0,0 +1,181 @@ +# GET /nodes/{node}/sdn/zones/{zone}/bridges + +Get a list of all bridges (vnets) that are part of a zone, as well as the ports that are members of that bridge. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | zone name or "localnetwork" | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_content.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_content.md new file mode 100644 index 00000000000..e5bf5bd3d15 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_content.md @@ -0,0 +1,129 @@ +# GET /nodes/{node}/sdn/zones/{zone}/content + +List zone content. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_ip_vrf.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_ip_vrf.md new file mode 100644 index 00000000000..7fb5fe9a798 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_sdn_zones_zone_ip_vrf.md @@ -0,0 +1,131 @@ +# GET /nodes/{node}/sdn/zones/{zone}/ip-vrf + +Get the IP VRF of an EVPN zone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| zone | string | yes | Name of an EVPN zone. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_services.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_services.md new file mode 100644 index 00000000000..9cd76b3d03a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_services.md @@ -0,0 +1,255 @@ +# GET /nodes/{node}/services + +Service list. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_services_service.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_services_service.md new file mode 100644 index 00000000000..acf39a4c52f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_services_service.md @@ -0,0 +1,127 @@ +# GET /nodes/{node}/services/{service} + +Directory index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_services_service_state.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_services_service_state.md new file mode 100644 index 00000000000..deb329478b5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_services_service_state.md @@ -0,0 +1,267 @@ +# GET /nodes/{node}/services/{service}/state + +Read service properties + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_status.md new file mode 100644 index 00000000000..af07c650a43 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_status.md @@ -0,0 +1,316 @@ +# GET /nodes/{node}/status + +Read node status + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage.md new file mode 100644 index 00000000000..84c928fe3b2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage.md @@ -0,0 +1,303 @@ +# GET /nodes/{node}/storage + +Get status for all datastores. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | no | Only list stores which support this content type. | +| enabled | boolean | no | Only list stores which are enabled (not disabled in config). | +| format | boolean | no | Include information about formats | +| storage | string | no | Only list status for specified storage | +| target | string | no | If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage.md new file mode 100644 index 00000000000..bba192cb5b5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage.md @@ -0,0 +1,111 @@ +# GET /nodes/{node}/storage/{storage} + +diridx + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": { + "subdir": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{subdir}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_content.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_content.md new file mode 100644 index 00000000000..676abcb9f16 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_content.md @@ -0,0 +1,270 @@ +# GET /nodes/{node}/storage/{storage}/content + +List storage content. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | no | Only list content of this type. | +| vmid | integer | no | Only list images for this VM | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_content_volume.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_content_volume.md new file mode 100644 index 00000000000..d386811bafd --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_content_volume.md @@ -0,0 +1,136 @@ +# GET /nodes/{node}/storage/{storage}/content/{volume} + +Get volume attributes + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_file_restore_download.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_file_restore_download.md new file mode 100644 index 00000000000..b54a0b8de31 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_file_restore_download.md @@ -0,0 +1,91 @@ +# GET /nodes/{node}/storage/{storage}/file-restore/download + +Extract a file or directory (as zip archive) from a PBS backup. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| filepath | string | yes | base64-path to the directory or file to download. | +| volume | string | yes | Backup volume ID or name. Currently only PBS snapshots are supported. | +| tar | boolean | no | Download dirs as 'tar.zst' instead of 'zip'. | + +## Returns + +```json +{ + "type": "any" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_file_restore_list.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_file_restore_list.md new file mode 100644 index 00000000000..96d885e0eb3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_file_restore_list.md @@ -0,0 +1,144 @@ +# GET /nodes/{node}/storage/{storage}/file-restore/list + +List files and directories for single file restore under the given path. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| filepath | string | yes | base64-path to the directory or file being listed, or "/". | +| volume | string | yes | Backup volume ID or name. Currently only PBS snapshots are supported. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_identity.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_identity.md new file mode 100644 index 00000000000..b4a124e918a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_identity.md @@ -0,0 +1,137 @@ +# GET /nodes/{node}/storage/{storage}/identity + +Return identity information for this storage instance. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_import_metadata.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_import_metadata.md new file mode 100644 index 00000000000..7e349b7e6f0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_import_metadata.md @@ -0,0 +1,214 @@ +# GET /nodes/{node}/storage/{storage}/import-metadata + +Get the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume | string | yes | Volume identifier for the guest archive/entry. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_prunebackups.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_prunebackups.md new file mode 100644 index 00000000000..350d0744851 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_prunebackups.md @@ -0,0 +1,178 @@ +# GET /nodes/{node}/storage/{storage}/prunebackups + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| type | string | no | Either 'qemu' or 'lxc'. Only consider backups for guests of this type. | +| vmid | integer | no | Only consider backups for this guest. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_rrd.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_rrd.md new file mode 100644 index 00000000000..17f18f52d68 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_rrd.md @@ -0,0 +1,125 @@ +# GET /nodes/{node}/storage/{storage}/rrd + +Read storage RRD statistics (returns PNG). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ds | string | yes | The list of datasources you want to display. | +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "properties": { + "filename": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_rrddata.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_rrddata.md new file mode 100644 index 00000000000..bae3c87cd6d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_rrddata.md @@ -0,0 +1,116 @@ +# GET /nodes/{node}/storage/{storage}/rrddata + +Read storage RRD statistics. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeframe | string | yes | Specify the time frame you are interested in. | +| cf | string | no | The RRD consolidation function | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_status.md new file mode 100644 index 00000000000..d71f990e496 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_storage_storage_status.md @@ -0,0 +1,173 @@ +# GET /nodes/{node}/storage/{storage}/status + +Read storage status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Audit", + "Datastore.AllocateSpace" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_subscription.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_subscription.md new file mode 100644 index 00000000000..f5272258653 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_subscription.md @@ -0,0 +1,198 @@ +# GET /nodes/{node}/subscription + +Read subscription info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_syslog.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_syslog.md new file mode 100644 index 00000000000..0a10645029e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_syslog.md @@ -0,0 +1,134 @@ +# GET /nodes/{node}/syslog + +Read system log + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| limit | integer | no | | +| service | string | no | Service ID | +| since | string | no | Display all log since this date-time string. | +| start | integer | no | | +| until | string | no | Display all log until this date-time string. | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Syslog" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks.md new file mode 100644 index 00000000000..fea78a99a94 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks.md @@ -0,0 +1,253 @@ +# GET /nodes/{node}/tasks + +Read task list for one node (finished tasks). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| errors | boolean | no | Only list tasks with a status of ERROR. | +| limit | integer | no | Only list this number of tasks. | +| since | integer | no | Only list tasks since this UNIX epoch. | +| source | string | no | List archived, active or all tasks. | +| start | integer | no | List tasks beginning from this offset. | +| statusfilter | string | no | List of Task States that should be returned. | +| typefilter | string | no | Only list tasks of this type (e.g., vzstart, vzdump). | +| until | integer | no | Only list tasks until this UNIX epoch. | +| userfilter | string | no | Only list tasks from this user. | +| vmid | integer | no | Only list tasks for this VM. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid.md new file mode 100644 index 00000000000..86ea261cc54 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid.md @@ -0,0 +1,82 @@ +# GET /nodes/{node}/tasks/{upid} + +upid_index + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | | + +## Request parameters + +None. + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "links": [ + { + "href": "{name}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid_log.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid_log.md new file mode 100644 index 00000000000..1456294f3d8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid_log.md @@ -0,0 +1,120 @@ +# GET /nodes/{node}/tasks/{upid}/log + +Read task log. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | The task's unique ID. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| download | boolean | no | Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters | +| limit | integer | no | The number of lines to read from the tasklog. | +| start | integer | no | Start at this line when reading the tasklog | + +## Returns + +```json +{ + "items": { + "properties": { + "n": { + "description": "Line number", + "type": "integer" + }, + "t": { + "description": "Line text", + "type": "string" + } + }, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Audit' permissions on '/nodes/' if they aren't the owner of the task.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid_status.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid_status.md new file mode 100644 index 00000000000..245d74de521 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_tasks_upid_status.md @@ -0,0 +1,141 @@ +# GET /nodes/{node}/tasks/{upid}/status + +Read task status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| upid | string | yes | The task's unique ID. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'Sys.Audit' permissions on '/nodes/' if they are not the owner of the task.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_time.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_time.md new file mode 100644 index 00000000000..9d2dbfa50a3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_time.md @@ -0,0 +1,108 @@ +# GET /nodes/{node}/time + +Read server time and time zone settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_version.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_version.md new file mode 100644 index 00000000000..0e9ff295163 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_version.md @@ -0,0 +1,86 @@ +# GET /nodes/{node}/version + +API version details + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_vncwebsocket.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_vncwebsocket.md new file mode 100644 index 00000000000..fc7ee01cd5b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_vncwebsocket.md @@ -0,0 +1,97 @@ +# GET /nodes/{node}/vncwebsocket + +Opens a websocket for VNC traffic. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | Port number returned by previous 'vncshell' call. | +| vncticket | string | yes | Ticket from previous call to 'vncshell'. | + +## Returns + +```json +{ + "properties": { + "port": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ], + "description": "You also need to pass a valid ticket (vncticket)." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_vzdump_defaults.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_vzdump_defaults.md new file mode 100644 index 00000000000..c3107c3c099 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_vzdump_defaults.md @@ -0,0 +1,510 @@ +# GET /nodes/{node}/vzdump/defaults + +Get the currently configured vzdump defaults. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | no | The storage identifier. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_nodes_node_vzdump_extractconfig.md b/docs/pve-api/markdown/endpoints/GET_nodes_node_vzdump_extractconfig.md new file mode 100644 index 00000000000..12aa879079f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_nodes_node_vzdump_extractconfig.md @@ -0,0 +1,68 @@ +# GET /nodes/{node}/vzdump/extractconfig + +Extract configuration from vzdump backup archive. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume | string | yes | Volume identifier | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The user needs 'VM.Backup' permissions on the backed up guest ID, and 'Datastore.AllocateSpace' on the backup storage.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_pools.md b/docs/pve-api/markdown/endpoints/GET_pools.md new file mode 100644 index 00000000000..e2d2c809932 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_pools.md @@ -0,0 +1,172 @@ +# GET /pools + +List pools or get pool configuration. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | no | | +| type | string | no | | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "description": "List all pools where you have Pool.Audit permissions on /pool/, or the pool specific with {poolid}", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_pools_poolid.md b/docs/pve-api/markdown/endpoints/GET_pools_poolid.md new file mode 100644 index 00000000000..0b8888852c6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_pools_poolid.md @@ -0,0 +1,157 @@ +# GET /pools/{poolid} + +Get pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}'). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Audit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_storage.md b/docs/pve-api/markdown/endpoints/GET_storage.md new file mode 100644 index 00000000000..6a96cb10c09 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_storage.md @@ -0,0 +1,102 @@ +# GET /storage + +Storage index. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | no | Only list storage of specific type | + +## Returns + +```json +{ + "items": { + "properties": { + "storage": { + "type": "string" + } + }, + "type": "object" + }, + "links": [ + { + "href": "{storage}", + "rel": "child" + } + ], + "type": "array" +} +``` + +## Permissions + +```json +{ + "description": "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_storage_storage.md b/docs/pve-api/markdown/endpoints/GET_storage_storage.md new file mode 100644 index 00000000000..46e2e2b4a4f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_storage_storage.md @@ -0,0 +1,70 @@ +# GET /storage/{storage} + +Read storage configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/GET_version.md b/docs/pve-api/markdown/endpoints/GET_version.md new file mode 100644 index 00000000000..af04c05a2ed --- /dev/null +++ b/docs/pve-api/markdown/endpoints/GET_version.md @@ -0,0 +1,99 @@ +# GET /version + +API version details, including some parts of the global datacenter config. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_domains.md b/docs/pve-api/markdown/endpoints/POST_access_domains.md new file mode 100644 index 00000000000..bcaf3da8966 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_domains.md @@ -0,0 +1,417 @@ +# POST /access/domains + +Add an authentication server. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | +| type | string | yes | Realm type. | +| acr-values | string | no | Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request. | +| audiences | string | no | A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'. | +| autocreate | boolean | no | Automatically create users if they do not exist. | +| base_dn | string | no | LDAP base domain name | +| bind_dn | string | no | LDAP bind domain name | +| capath | string | no | Path to the CA certificate store | +| case-sensitive | boolean | no | username is case-sensitive | +| cert | string | no | Path to the client certificate | +| certkey | string | no | Path to the client certificate key | +| check-connection | boolean | no | Check bind connection to the server. | +| client-id | string | no | OpenID Client ID | +| client-key | string | no | OpenID Client Key | +| comment | string | no | Description. | +| default | boolean | no | Use this as default realm | +| domain | string | no | AD domain name | +| filter | string | no | LDAP filter for user sync. | +| group_classes | string | no | The objectclasses for groups. | +| group_dn | string | no | LDAP base domain name for group sync. If not set, the base_dn will be used. | +| group_filter | string | no | LDAP filter for group sync. | +| group_name_attr | string | no | LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name. | +| groups-autocreate | boolean | no | Automatically create groups if they do not exist. | +| groups-claim | string | no | OpenID claim used to retrieve groups with. | +| groups-overwrite | boolean | no | All groups will be overwritten for the user on login. | +| issuer-url | string | no | OpenID Issuer Url | +| mode | string | no | LDAP protocol mode. | +| password | string | no | LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'. | +| port | integer | no | Server port. | +| prompt | string | no | Specifies whether the Authorization Server prompts the End-User for reauthentication and consent. | +| query-userinfo | boolean | no | Enables querying the userinfo endpoint for claims values. | +| scopes | string | no | Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'. | +| secure | boolean | no | Use secure LDAPS protocol. DEPRECATED: use 'mode' instead. | +| server1 | string | no | Server IP address (or DNS name) | +| server2 | string | no | Fallback Server IP address (or DNS name) | +| sslversion | string | no | LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! | +| sync_attributes | string | no | 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. | +| sync-defaults-options | string | no | The default options for behavior of synchronizations. | +| tfa | string | no | Use Two-factor authentication. | +| user_attr | string | no | LDAP user attribute name | +| user_classes | string | no | The objectclasses for users. | +| username-claim | string | no | OpenID claim used to generate the unique username. | +| verify | boolean | no | Verify the server's SSL certificate | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_domains_realm_sync.md b/docs/pve-api/markdown/endpoints/POST_access_domains_realm_sync.md new file mode 100644 index 00000000000..6875c2cf14b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_domains_realm_sync.md @@ -0,0 +1,146 @@ +# POST /access/domains/{realm}/sync + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| enable-new | boolean | yes | Enable newly synced users immediately. | +| full | boolean | yes | 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. | +| purge | boolean | yes | DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync. | +| remove-vanished | string | yes | 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). | +| scope | string | yes | Select what to sync. | +| dry-run | boolean | no | If set, does not write anything. | + +## Returns + +```json +{ + "description": "Worker Task-UPID", + "type": "string" +} +``` + +## Permissions + +```json +{ + "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/'." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_groups.md b/docs/pve-api/markdown/endpoints/POST_access_groups.md new file mode 100644 index 00000000000..b1547a23d63 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_groups.md @@ -0,0 +1,75 @@ +# POST /access/groups + +Create new group. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_openid_auth_url.md b/docs/pve-api/markdown/endpoints/POST_access_openid_auth_url.md new file mode 100644 index 00000000000..356ef7ebb38 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_openid_auth_url.md @@ -0,0 +1,68 @@ +# POST /access/openid/auth-url + +Get the OpenId Authorization Url for the specified realm. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | +| redirect-url | string | yes | Redirection Url. The client should set this to the used server url (location.origin). | + +## Returns + +```json +{ + "description": "Redirection URL.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_openid_login.md b/docs/pve-api/markdown/endpoints/POST_access_openid_login.md new file mode 100644 index 00000000000..1c9cfa1871c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_openid_login.md @@ -0,0 +1,106 @@ +# POST /access/openid/login + +Verify OpenID authorization code and create a ticket. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| code | string | yes | OpenId authorization code. | +| redirect-url | string | yes | Redirection Url. The client should set this to the used server url (location.origin). | +| state | string | yes | OpenId state. | + +## Returns + +```json +{ + "properties": { + "CSRFPreventionToken": { + "type": "string" + }, + "cap": { + "type": "object" + }, + "clustername": { + "optional": 1, + "type": "string" + }, + "ticket": { + "type": "string" + }, + "username": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_roles.md b/docs/pve-api/markdown/endpoints/POST_access_roles.md new file mode 100644 index 00000000000..f9ce53a6536 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_roles.md @@ -0,0 +1,76 @@ +# POST /access/roles + +Create new role. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | +| privs | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_tfa_userid.md b/docs/pve-api/markdown/endpoints/POST_access_tfa_userid.md new file mode 100644 index 00000000000..4dc2ab180ae --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_tfa_userid.md @@ -0,0 +1,174 @@ +# POST /access/tfa/{userid} + +Add a TFA entry for a user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | TFA Entry Type. | +| challenge | string | no | When responding to a u2f challenge: the original challenge string | +| description | string | no | A description to distinguish multiple entries from one another | +| password | string | no | The current password of the user performing the change. | +| totp | string | no | A totp URI. | +| value | string | no | The current value for the provided totp URI, or a Webauthn/U2F challenge response | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_ticket.md b/docs/pve-api/markdown/endpoints/POST_access_ticket.md new file mode 100644 index 00000000000..8bce4d054b3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_ticket.md @@ -0,0 +1,150 @@ +# POST /access/ticket + +Create or verify authentication ticket. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | The secret password. This can also be a valid ticket. | +| username | string | yes | User name | +| new-format | boolean | no | This parameter is now ignored and assumed to be 1. | +| otp | string | no | One-time password for Two-factor authentication. | +| path | string | no | Verify ticket, and check if user have access 'privs' on 'path' | +| privs | string | no | Verify ticket, and check if user have access 'privs' on 'path' | +| realm | string | no | You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @. | +| tfa-challenge | string | no | The signed TFA challenge string the user wants to respond to. | + +## Returns + +```json +{ + "properties": { + "CSRFPreventionToken": { + "optional": 1, + "type": "string" + }, + "clustername": { + "optional": 1, + "type": "string" + }, + "ticket": { + "optional": 1, + "type": "string" + }, + "username": { + "type": "string" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "description": "You need to pass valid credientials.", + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_users.md b/docs/pve-api/markdown/endpoints/POST_access_users.md new file mode 100644 index 00000000000..5123c6ac3a0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_users.md @@ -0,0 +1,157 @@ +# POST /access/users + +Create new user. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | +| comment | string | no | | +| email | string | no | | +| enable | boolean | no | Enable the account (default). You can set this to '0' to disable the account | +| expire | integer | no | Account expiration date (seconds since epoch). '0' means no expiration date. | +| firstname | string | no | | +| groups | string | no | | +| keys | string | no | Keys for two factor auth (yubico). | +| lastname | string | no | | +| password | string | no | Initial password. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_users_userid_token_tokenid.md b/docs/pve-api/markdown/endpoints/POST_access_users_userid_token_tokenid.md new file mode 100644 index 00000000000..467ef537095 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_users_userid_token_tokenid.md @@ -0,0 +1,181 @@ +# POST /access/users/{userid}/token/{tokenid} + +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! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| expire | integer | no | API token expiration date (seconds since epoch). '0' means no expiration date. | +| privsep | boolean | no | Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_access_vncticket.md b/docs/pve-api/markdown/endpoints/POST_access_vncticket.md new file mode 100644 index 00000000000..34c14cd219f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_access_vncticket.md @@ -0,0 +1,88 @@ +# POST /access/vncticket + +verify VNC authentication ticket. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| authid | string | yes | UserId or token | +| path | string | yes | Verify ticket, and check if user have access 'privs' on 'path' | +| privs | string | yes | Verify ticket, and check if user have access 'privs' on 'path' | +| vncticket | string | yes | The VNC ticket. | +| port | integer | no | Verify that the ticket is valid for this port. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "You need to pass valid credientials.", + "user": "world" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_acme_account.md b/docs/pve-api/markdown/endpoints/POST_cluster_acme_account.md new file mode 100644 index 00000000000..da611699406 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_acme_account.md @@ -0,0 +1,92 @@ +# POST /cluster/acme/account + +Register a new ACME account with CA. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| contact | string | yes | Contact email addresses. | +| directory | string | no | URL of ACME CA directory endpoint. | +| eab-hmac-key | string | no | HMAC key for External Account Binding. | +| eab-kid | string | no | Key Identifier for External Account Binding. | +| name | string | no | ACME account config file name. | +| tos_url | string | no | URL of CA TermsOfService - setting this indicates agreement. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_acme_plugins.md b/docs/pve-api/markdown/endpoints/POST_cluster_acme_plugins.md new file mode 100644 index 00000000000..417406f2ac7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_acme_plugins.md @@ -0,0 +1,280 @@ +# POST /cluster/acme/plugins + +Add ACME plugin configuration. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | ACME Plugin ID name | +| type | string | yes | ACME challenge type. | +| api | string | no | API plugin name | +| data | string | no | DNS plugin data. (base64 encoded) | +| disable | boolean | no | Flag to disable the config. | +| nodes | string | no | List of cluster node names. | +| validation-delay | integer | no | Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_backup.md b/docs/pve-api/markdown/endpoints/POST_cluster_backup.md new file mode 100644 index 00000000000..ceadc796eaf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_backup.md @@ -0,0 +1,398 @@ +# POST /cluster/backup + +Create new vzdump backup job. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| all | boolean | no | Backup all known guest systems on this host. | +| bwlimit | integer | no | Limit I/O bandwidth (in KiB/s). | +| comment | string | no | Description for the Job. | +| compress | string | no | Compress dump file. | +| dow | string | no | Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| dumpdir | string | no | Store resulting files to specified directory. | +| enabled | boolean | no | Enable or disable the job. | +| exclude | string | no | Exclude specified guest systems (assumes --all) | +| exclude-path | array | no | Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory. | +| fleecing | string | no | Options for backup fleecing (VM only). | +| id | string | no | Job ID (will be autogenerated). | +| ionice | integer | no | 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. | +| lockwait | integer | no | Maximal time to wait for the global lock (minutes). | +| mailnotification | string | no | Deprecated: use notification targets/matchers instead. Specify when to send a notification mail | +| mailto | string | no | Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications. | +| mode | string | no | Backup mode. | +| node | string | no | Only run if executed on this node. | +| notes-template | string | no | 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. | +| notification-mode | string | no | 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. | +| pbs-change-detection-mode | string | no | PBS mode used to detect file changes and switch encoding format for container backups. | +| performance | string | no | Other performance-related settings. | +| pigz | integer | no | Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count. | +| pool | string | no | Backup all known guest systems included in the specified pool. | +| protected | boolean | no | If true, mark backup(s) as protected. | +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| quiet | boolean | no | Be quiet. | +| remove | boolean | no | Prune older backups according to 'prune-backups'. | +| repeat-missed | boolean | no | If true, the job will be run as soon as possible if it was missed while the scheduler was not running. | +| schedule | string | no | Backup schedule. The format is a subset of `systemd` calendar events. | +| script | string | no | Use specified hook script. | +| starttime | string | no | Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| stdexcludes | boolean | no | Exclude temporary files and logs. | +| stop | boolean | no | Stop running backup jobs on this host. | +| stopwait | integer | no | Maximal time to wait until a guest system is stopped (minutes). | +| storage | string | no | Store resulting file to this storage. | +| tmpdir | string | no | Store temporary files to specified directory. | +| vmid | string | no | The ID of the guest system you want to backup. | +| zstd | integer | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_migrate.md b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_migrate.md new file mode 100644 index 00000000000..399e1d5a6ad --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_migrate.md @@ -0,0 +1,111 @@ +# POST /cluster/bulk-action/guest/migrate + +Bulk migrate all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| online | boolean | no | Enable live migration for VMs and restart migration for CTs. | +| vms | array | no | Only consider guests from this list of VMIDs. | +| with-local-disks | boolean | no | Enable live storage migration for local disk | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_shutdown.md b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_shutdown.md new file mode 100644 index 00000000000..31122913cf9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_shutdown.md @@ -0,0 +1,106 @@ +# POST /cluster/bulk-action/guest/shutdown + +Bulk shutdown all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force-stop | boolean | no | Makes sure the Guest stops after the timeout. | +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| timeout | integer | no | Default shutdown timeout in seconds if none is configured for the guest. | +| vms | array | no | Only consider guests from this list of VMIDs. | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_start.md b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_start.md new file mode 100644 index 00000000000..56ecea4edc5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_start.md @@ -0,0 +1,97 @@ +# POST /cluster/bulk-action/guest/start + +Bulk start or resume all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| timeout | integer | no | Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration). | +| vms | array | no | Only consider guests from this list of VMIDs. | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_suspend.md b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_suspend.md new file mode 100644 index 00000000000..72cebdc8391 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_bulk_action_guest_suspend.md @@ -0,0 +1,108 @@ +# POST /cluster/bulk-action/guest/suspend + +Bulk suspend all guests on the cluster. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max-workers | integer | no | Defines the maximum number of tasks running concurrently. | +| maxworkers | integer | no | Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead. | +| statestorage | string | no | The storage for the VM state. | +| to-disk | boolean | no | If set, suspends the guests to disk. Will be resumed on next start. | +| vms | array | no | Only consider guests from this list of VMIDs. | + +## Returns + +```json +{ + "description": "UPID of the worker", + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_config.md b/docs/pve-api/markdown/endpoints/POST_cluster_config.md new file mode 100644 index 00000000000..b33a217715a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_config.md @@ -0,0 +1,101 @@ +# POST /cluster/config + +Generate new cluster configuration. If no links given, default to local IP address as link0. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| clustername | string | yes | The name of the cluster. | +| link[n] | string | no | Address and priority information of a single corosync link. (up to 8 links supported; link0..link7) | +| nodeid | integer | no | Node id for this node. | +| token-coefficient | integer | no | Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details. | +| votes | integer | no | Number of votes for this node. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_config_join.md b/docs/pve-api/markdown/endpoints/POST_cluster_config_join.md new file mode 100644 index 00000000000..cfc0cc8ba36 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_config_join.md @@ -0,0 +1,110 @@ +# POST /cluster/config/join + +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). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fingerprint | string | yes | Certificate SHA 256 fingerprint. | +| hostname | string | yes | Hostname (or IP) of an existing cluster member. | +| password | string | yes | Superuser (root) password of peer node. | +| force | boolean | no | Do not throw error if node already exists. | +| link[n] | string | no | Address and priority information of a single corosync link. (up to 8 links supported; link0..link7) | +| nodeid | integer | no | Node id for this node. | +| votes | integer | no | Number of votes for this node | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_config_nodes_node.md b/docs/pve-api/markdown/endpoints/POST_cluster_config_nodes_node.md new file mode 100644 index 00000000000..a70ae4b2f9f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_config_nodes_node.md @@ -0,0 +1,142 @@ +# POST /cluster/config/nodes/{node} + +Adds a node to the cluster configuration. This call is for internal use. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| apiversion | integer | no | The JOIN_API_VERSION of the new node. | +| force | boolean | no | Do not throw error if node already exists. | +| link[n] | string | no | Address and priority information of a single corosync link. (up to 8 links supported; link0..link7) | +| new_node_ip | string | no | IP Address of node to add. Used as fallback if no links are given. | +| nodeid | integer | no | Node id for this node. | +| votes | integer | no | Number of votes for this node | + +## Returns + +```json +{ + "properties": { + "corosync_authkey": { + "type": "string" + }, + "corosync_conf": { + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_firewall_aliases.md b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_aliases.md new file mode 100644 index 00000000000..cc592f9fc77 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_aliases.md @@ -0,0 +1,84 @@ +# POST /cluster/firewall/aliases + +Create IP or Network Alias. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | Alias name. | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_firewall_groups.md b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_groups.md new file mode 100644 index 00000000000..d615d183330 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_groups.md @@ -0,0 +1,94 @@ +# POST /cluster/firewall/groups + +Create new security group. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_firewall_groups_group.md b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_groups_group.md new file mode 100644 index 00000000000..64d795bfa25 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_groups_group.md @@ -0,0 +1,210 @@ +# POST /cluster/firewall/groups/{group} + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_firewall_ipset.md b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_ipset.md new file mode 100644 index 00000000000..bc964e801db --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_ipset.md @@ -0,0 +1,94 @@ +# POST /cluster/firewall/ipset + +Create new IPSet + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_ipset_name.md new file mode 100644 index 00000000000..23a570f7a95 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_ipset_name.md @@ -0,0 +1,91 @@ +# POST /cluster/firewall/ipset/{name} + +Add IP or Network to IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_firewall_rules.md b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_rules.md new file mode 100644 index 00000000000..3f486576c88 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_firewall_rules.md @@ -0,0 +1,201 @@ +# POST /cluster/firewall/rules + +Create new rule. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_ha_groups.md b/docs/pve-api/markdown/endpoints/POST_cluster_ha_groups.md new file mode 100644 index 00000000000..7e8c910c5a6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_ha_groups.md @@ -0,0 +1,114 @@ +# POST /cluster/ha/groups + +Create a new HA group. (deprecated in favor of HA rules) + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | +| nodes | string | yes | List of cluster node names with optional priority. | +| comment | string | no | Description. | +| nofailback | boolean | no | 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. | +| restricted | boolean | no | Resources bound to restricted groups may only run on nodes defined by the group. | +| type | string | no | Group type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources.md b/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources.md new file mode 100644 index 00000000000..5e29ffb0149 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources.md @@ -0,0 +1,146 @@ +# POST /cluster/ha/resources + +Create a new HA resource. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | +| auto-rebalance | boolean | no | HA resource may be migrated during automatic rebalancing | +| comment | string | no | Description. | +| failback | boolean | no | 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. | +| group | string | no | The HA group identifier. | +| max_relocate | integer | no | Maximal number of resource relocate tries when a resource fails to start. | +| max_restart | integer | no | 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. | +| state | string | no | Requested resource state. | +| type | string | no | Resource type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources_sid_migrate.md b/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources_sid_migrate.md new file mode 100644 index 00000000000..708877bdec1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources_sid_migrate.md @@ -0,0 +1,158 @@ +# POST /cluster/ha/resources/{sid}/migrate + +Request resource migration (online) to another node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources_sid_relocate.md b/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources_sid_relocate.md new file mode 100644 index 00000000000..d0a2a646f31 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_ha_resources_sid_relocate.md @@ -0,0 +1,166 @@ +# POST /cluster/ha/resources/{sid}/relocate + +Request resource relocation to another node. This stops the service on the old node, and restarts it on the target node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | Target node. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_ha_rules.md b/docs/pve-api/markdown/endpoints/POST_cluster_ha_rules.md new file mode 100644 index 00000000000..7b03df607d5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_ha_rules.md @@ -0,0 +1,144 @@ +# POST /cluster/ha/rules + +Create HA rule. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| resources | string | yes | 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). | +| rule | string | yes | HA rule identifier. | +| type | string | yes | HA rule type. | +| affinity | string | no | 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'). | +| comment | string | no | HA rule description. | +| disable | boolean | no | Whether the HA rule is disabled. | +| nodes | string | no | List of cluster node names with optional priority. | +| strict | boolean | no | Describes whether the node affinity rule is strict or non-strict. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_ha_status_arm_ha.md b/docs/pve-api/markdown/endpoints/POST_cluster_ha_status_arm_ha.md new file mode 100644 index 00000000000..2c1ed5c2082 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_ha_status_arm_ha.md @@ -0,0 +1,60 @@ +# POST /cluster/ha/status/arm-ha + +Request re-arming the HA stack after it was disarmed. + +## Path parameters + +None. + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_ha_status_disarm_ha.md b/docs/pve-api/markdown/endpoints/POST_cluster_ha_status_disarm_ha.md new file mode 100644 index 00000000000..7f46b97b58a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_ha_status_disarm_ha.md @@ -0,0 +1,72 @@ +# POST /cluster/ha/status/disarm-ha + +Request disarming the HA stack, releasing all watchdogs cluster-wide. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| resource-mode | string | yes | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_jobs_realm_sync_id.md b/docs/pve-api/markdown/endpoints/POST_cluster_jobs_realm_sync_id.md new file mode 100644 index 00000000000..5c94f4bd58c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_jobs_realm_sync_id.md @@ -0,0 +1,156 @@ +# POST /cluster/jobs/realm-sync/{id} + +Create new realm-sync job. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the job. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| schedule | string | yes | Backup schedule. The format is a subset of `systemd` calendar events. | +| comment | string | no | Description for the Job. | +| enable-new | boolean | no | Enable newly synced users immediately. | +| enabled | boolean | no | Determines if the job is enabled. | +| realm | string | no | Authentication domain ID | +| remove-vanished | string | no | 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). | +| scope | string | no | Select what to sync. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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/'." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_mapping_dir.md b/docs/pve-api/markdown/endpoints/POST_cluster_mapping_dir.md new file mode 100644 index 00000000000..c231f98e69f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_mapping_dir.md @@ -0,0 +1,101 @@ +# POST /cluster/mapping/dir + +Create a new directory mapping. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the directory mapping | +| map | array | yes | A list of maps for the cluster nodes. | +| description | string | no | Description of the directory mapping | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/dir", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_mapping_pci.md b/docs/pve-api/markdown/endpoints/POST_cluster_mapping_pci.md new file mode 100644 index 00000000000..fa477e2d214 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_mapping_pci.md @@ -0,0 +1,139 @@ +# POST /cluster/mapping/pci + +Create a new hardware mapping. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical PCI mapping. | +| map | array | yes | A list of maps for the cluster nodes. | +| description | string | no | Description of the logical PCI device. | +| live-migration-capable | boolean | no | Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work. | +| mdev | boolean | no | Marks the device(s) as being capable of providing mediated devices. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/pci", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_mapping_usb.md b/docs/pve-api/markdown/endpoints/POST_cluster_mapping_usb.md new file mode 100644 index 00000000000..cbd8441fb45 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_mapping_usb.md @@ -0,0 +1,112 @@ +# POST /cluster/mapping/usb + +Create a new hardware mapping. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical USB mapping. | +| map | array | yes | A list of maps for the cluster nodes. | +| description | string | no | Description of the logical USB device. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/usb", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_metrics_server_id.md b/docs/pve-api/markdown/endpoints/POST_cluster_metrics_server_id.md new file mode 100644 index 00000000000..89ce4e3b828 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_metrics_server_id.md @@ -0,0 +1,271 @@ +# POST /cluster/metrics/server/{id} + +Create a new external metric server config + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the entry. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | server network port | +| server | string | yes | server dns name or IP address | +| type | string | yes | Plugin type. | +| api-path-prefix | string | no | An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy. | +| bucket | string | no | The InfluxDB bucket/db. Only necessary when using the http v2 api. | +| disable | boolean | no | Flag to disable the plugin. | +| influxdbproto | string | no | | +| max-body-size | integer | no | InfluxDB max-body-size in bytes. Requests are batched up to this size. | +| mtu | integer | no | MTU for metrics transmission over UDP | +| organization | string | no | The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api. | +| otel-compression | string | no | Compression algorithm for requests | +| otel-headers | string | no | Custom HTTP headers (JSON format, base64 encoded) | +| otel-max-body-size | integer | no | Maximum request body size in bytes | +| otel-path | string | no | OTLP endpoint path | +| otel-protocol | string | no | HTTP protocol | +| otel-resource-attributes | string | no | Additional resource attributes as JSON, base64 encoded | +| otel-timeout | integer | no | HTTP request timeout in seconds | +| otel-verify-ssl | boolean | no | Verify SSL certificates | +| path | string | no | root graphite path (ex: proxmox.mycluster.mykey) | +| proto | string | no | Protocol to send graphite data. TCP or UDP (default) | +| timeout | integer | no | graphite TCP socket timeout (default=1) | +| token | string | no | The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead. | +| verify-certificate | boolean | no | Set to 0 to disable certificate verification for https endpoints. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_gotify.md b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_gotify.md new file mode 100644 index 00000000000..5c09a612670 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_gotify.md @@ -0,0 +1,139 @@ +# POST /cluster/notifications/endpoints/gotify + +Create a new gotify endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | +| server | string | yes | Server URL | +| token | string | yes | Secret token | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_sendmail.md b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_sendmail.md new file mode 100644 index 00000000000..abf1c1c684e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_sendmail.md @@ -0,0 +1,163 @@ +# POST /cluster/notifications/endpoints/sendmail + +Create a new sendmail endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | +| author | string | no | Author of the mail | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | +| from-address | string | no | `From` address for the mail | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_smtp.md b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_smtp.md new file mode 100644 index 00000000000..d6ac5c3863c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_smtp.md @@ -0,0 +1,201 @@ +# POST /cluster/notifications/endpoints/smtp + +Create a new smtp endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| from-address | string | yes | `From` address for the mail | +| name | string | yes | The name of the endpoint. | +| server | string | yes | The address of the SMTP server. | +| author | string | no | Author of the mail. Defaults to 'Proxmox VE'. | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | +| mode | string | no | Determine which encryption method shall be used for the connection. | +| password | string | no | Password for SMTP authentication | +| port | integer | no | 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. | +| username | string | no | Username for SMTP authentication | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_webhook.md b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_webhook.md new file mode 100644 index 00000000000..29848d4469c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_endpoints_webhook.md @@ -0,0 +1,170 @@ +# POST /cluster/notifications/endpoints/webhook + +Create a new webhook endpoint + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| method | string | yes | HTTP method | +| name | string | yes | The name of the endpoint. | +| url | string | yes | Server URL | +| body | string | no | HTTP body, base64 encoded | +| comment | string | no | Comment | +| disable | boolean | no | Disable this target | +| header | array | no | HTTP headers to set. These have to be formatted as a property string in the format name=,value= | +| secret | array | no | Secrets to set. These have to be formatted as a property string in the format name=,value= | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_notifications_matchers.md b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_matchers.md new file mode 100644 index 00000000000..ed9730ae620 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_matchers.md @@ -0,0 +1,144 @@ +# POST /cluster/notifications/matchers + +Create a new matcher + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the matcher. | +| comment | string | no | Comment | +| disable | boolean | no | Disable this matcher | +| invert-match | boolean | no | Invert match of the whole matcher | +| match-calendar | array | no | Match notification timestamp | +| match-field | array | no | Metadata fields to match (regex or exact match). Must be in the form (regex\|exact):= | +| match-severity | array | no | Notification severities to match | +| mode | string | no | Choose between 'all' and 'any' for when multiple properties are specified | +| target | array | no | Targets to notify on match | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_notifications_targets_name_test.md b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_targets_name_test.md new file mode 100644 index 00000000000..1da59df9e89 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_notifications_targets_name_test.md @@ -0,0 +1,104 @@ +# POST /cluster/notifications/targets/{name}/test + +Send a test notification to a provided target. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the target. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Audit" + ] + ], + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Use" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_qemu_custom_cpu_models.md b/docs/pve-api/markdown/endpoints/POST_cluster_qemu_custom_cpu_models.md new file mode 100644 index 00000000000..6a6131248aa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_qemu_custom_cpu_models.md @@ -0,0 +1,242 @@ +# POST /cluster/qemu/custom-cpu-models + +Add a custom CPU model definition. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | Name for the custom CPU model. The 'custom-' prefix is optional. | +| reported-model | string | yes | 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. | +| flags | string | no | 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 | +| guest-phys-bits | integer | no | Number of physical address bits available to the guest. | +| hidden | boolean | no | Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture. | +| hv-vendor-id | string | no | The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID. | +| level | integer | no | 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. | +| phys-bits | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/cpu", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_replication.md b/docs/pve-api/markdown/endpoints/POST_cluster_replication.md new file mode 100644 index 00000000000..18d2f3bdd0d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_replication.md @@ -0,0 +1,128 @@ +# POST /cluster/replication + +Create a new replication job + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| target | string | yes | Target node. | +| type | string | yes | Section type. | +| comment | string | no | Description. | +| disable | boolean | no | Flag to disable/deactivate the entry. | +| rate | number | no | Rate limit in mbps (megabytes per second) as floating point number. | +| remove_job | string | no | 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. | +| schedule | string | no | Storage replication schedule. The format is a subset of `systemd` calendar events. | +| source | string | no | For internal use, to detect if the guest was stolen. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_controllers.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_controllers.md new file mode 100644 index 00000000000..8bb303af8be --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_controllers.md @@ -0,0 +1,222 @@ +# POST /cluster/sdn/controllers + +Create a new sdn controller object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | +| type | string | yes | Plugin type. | +| asn | integer | no | autonomous system number | +| bgp-mode | string | no | Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. | +| bgp-multipath-as-path-relax | boolean | no | Consider different AS paths of equal length for multipath computation. | +| ebgp | boolean | no | Enable eBGP (remote-as external). | +| ebgp-multihop | integer | no | Set maximum amount of hops for eBGP peers. | +| fabric | string | no | SDN fabric to use as underlay for this EVPN controller. | +| isis-domain | string | no | Name of the IS-IS domain. | +| isis-ifaces | string | no | Comma-separated list of interfaces where IS-IS should be active. | +| isis-net | string | no | Network Entity title for this node in the IS-IS network. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| loopback | string | no | Name of the loopback/dummy interface that provides the Router-IP. | +| node | string | no | The cluster node name. | +| nodes | string | no | List of cluster node names. | +| peer-group-name | string | no | Name of the peer group for this EVPN controller | +| peers | string | no | peers address list. | +| route-map-in | string | no | Route Map that should be applied for incoming routes | +| route-map-out | string | no | Route Map that should be applied for outgoing routes | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_dns.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_dns.md new file mode 100644 index 00000000000..07147effbc9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_dns.md @@ -0,0 +1,124 @@ +# POST /cluster/sdn/dns + +Create a new sdn dns object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | +| key | string | yes | | +| type | string | yes | Plugin type. | +| url | string | yes | | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| reversemaskv6 | integer | no | | +| reversev6mask | integer | no | | +| ttl | integer | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_fabrics_fabric.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_fabrics_fabric.md new file mode 100644 index 00000000000..51ea2c4b4ba --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_fabrics_fabric.md @@ -0,0 +1,240 @@ +# POST /cluster/sdn/fabrics/fabric + +Add a fabric + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| redistribute | array | yes | | +| area | string | no | OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust. | +| csnp_interval | number | no | The csnp_interval property for Openfabric | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| hello_interval | number | no | The hello_interval property for Openfabric | +| ip_prefix | string | no | The IP prefix for Node IPs | +| ip6_prefix | string | no | The IP prefix for Node IPs | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| persistent_keepalive | number | no | 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 | +| route_filter | string | no | A prefix list that should be used for filtering routes that are to be installed into the kernel routing table | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_fabrics_node_fabric_id.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_fabrics_node_fabric_id.md new file mode 100644 index 00000000000..02054c5df6e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_fabrics_node_fabric_id.md @@ -0,0 +1,337 @@ +# POST /cluster/sdn/fabrics/node/{fabric_id} + +Add a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| interfaces | array | yes | | +| node_id | string | yes | Identifier for nodes in an SDN fabric | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| allowed_ips | array | no | A list of IPs that are routable via this node in the WireGuard fabric. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| endpoint | string | no | The endpoint used for connecting to this node. | +| ip | string | no | IPv4 address for this node | +| ip6 | string | no | IPv6 address for this node | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| peers | array | no | | +| public_key | string | no | The public key for the external node. | +| role | string | no | The role of this node in the WireGuard fabric. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_ipams.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_ipams.md new file mode 100644 index 00000000000..f7df4177101 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_ipams.md @@ -0,0 +1,114 @@ +# POST /cluster/sdn/ipams + +Create a new sdn ipam object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | +| type | string | yes | Plugin type. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| section | integer | no | | +| token | string | no | | +| url | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_lock.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_lock.md new file mode 100644 index 00000000000..470dc8b1011 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_lock.md @@ -0,0 +1,71 @@ +# POST /cluster/sdn/lock + +Acquire global lock for SDN configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| allow-pending | boolean | no | if true, allow acquiring lock even though there are pending changes | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_prefix_lists.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_prefix_lists.md new file mode 100644 index 00000000000..2fa8ec8a889 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_prefix_lists.md @@ -0,0 +1,126 @@ +# POST /cluster/sdn/prefix-lists + +Create Prefix List + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| entries | array | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_prefix_lists_id_entries.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_prefix_lists_id_entries.md new file mode 100644 index 00000000000..a08011fc837 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_prefix_lists_id_entries.md @@ -0,0 +1,117 @@ +# POST /cluster/sdn/prefix-lists/{id}/entries + +Create Prefix List Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | | +| prefix | string | yes | | +| ge | integer | no | | +| le | integer | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| seq | integer | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_rollback.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_rollback.md new file mode 100644 index 00000000000..c1cefdb7275 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_rollback.md @@ -0,0 +1,78 @@ +# POST /cluster/sdn/rollback + +Rollback pending changes to SDN configuration + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | +| release-lock | boolean | no | When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_route_maps_entries.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_route_maps_entries.md new file mode 100644 index 00000000000..0cdaa11a41a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_route_maps_entries.md @@ -0,0 +1,200 @@ +# POST /cluster/sdn/route-maps/entries + +Create Route Map entry + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Matching policy of a route map entry. | +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | +| call | string | no | The SDN route map identifier | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| exit-action | string | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| match | array | no | | +| set | array | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets.md new file mode 100644 index 00000000000..7e58b3f55cc --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets.md @@ -0,0 +1,126 @@ +# POST /cluster/sdn/vnets + +Create a new sdn vnet object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| zone | string | yes | Name of the zone this VNet belongs to. | +| alias | string | no | Alias name of the VNet. | +| isolate-ports | boolean | no | If true, sets the isolated property for all interfaces on the bridge of this VNet. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| tag | integer | no | VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones). | +| type | string | no | Type of the VNet. | +| vlanaware | boolean | no | Allow VLANs to pass through this vnet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_firewall_rules.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_firewall_rules.md new file mode 100644 index 00000000000..1ae1f846c5c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_firewall_rules.md @@ -0,0 +1,200 @@ +# POST /cluster/sdn/vnets/{vnet}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_ips.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_ips.md new file mode 100644 index 00000000000..506cee984d1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_ips.md @@ -0,0 +1,97 @@ +# POST /cluster/sdn/vnets/{vnet}/ips + +Create IP Mapping in a VNet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ip | string | yes | The IP address to associate with the given MAC address | +| zone | string | yes | The SDN zone object identifier. | +| mac | string | no | Unicast MAC address. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_subnets.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_subnets.md new file mode 100644 index 00000000000..cd1d5becae7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_vnets_vnet_subnets.md @@ -0,0 +1,125 @@ +# POST /cluster/sdn/vnets/{vnet}/subnets + +Create a new sdn subnet object. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | associated vnet | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| type | string | yes | | +| dhcp-dns-server | string | no | IP address for the DNS server | +| dhcp-range | array | no | A list of DHCP ranges for this subnet | +| dnszoneprefix | string | no | dns domain zone prefix ex: 'adm' -> .adm.mydomain.com | +| gateway | string | no | Subnet Gateway: Will be assign on vnet for layer3 zones | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| snat | boolean | no | enable masquerade for this subnet if pve-firewall | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_cluster_sdn_zones.md b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_zones.md new file mode 100644 index 00000000000..b4d9560f766 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_cluster_sdn_zones.md @@ -0,0 +1,295 @@ +# POST /cluster/sdn/zones + +Create a new sdn zone object. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | Plugin type. | +| zone | string | yes | The SDN zone object identifier. | +| advertise-subnets | boolean | no | Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). | +| bridge | string | no | The bridge for which VLANs should be managed. | +| bridge-disable-mac-learning | boolean | no | Disable auto mac learning. | +| controller | string | no | Controller for this zone. | +| dhcp | string | no | Type of the DHCP backend for this zone | +| disable-arp-nd-suppression | boolean | no | Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. | +| dns | string | no | dns api server | +| dnszone | string | no | dns domain zone ex: mydomain.com | +| dp-id | integer | no | Faucet dataplane id | +| exitnodes | string | no | List of cluster node names. | +| exitnodes-local-routing | boolean | no | Allow exitnodes to connect to EVPN guests. | +| exitnodes-primary | string | no | Force traffic through this exitnode first. | +| fabric | string | no | SDN fabric to use as underlay for this VXLAN zone. | +| ipam | string | no | use a specific ipam | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| mac | string | no | Anycast logical router mac address. | +| mtu | integer | no | MTU of the zone, will be used for the created VNet bridges. | +| nodes | string | no | List of cluster node names. | +| peers | string | no | Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. | +| reversedns | string | no | reverse dns api server | +| rt-import | string | no | List of Route Targets that should be imported into the VRF of the zone. | +| secondary-controllers | array | no | Additional controllers. | +| tag | integer | no | Service-VLAN Tag (outer VLAN) | +| vlan-protocol | string | no | Which VLAN protocol should be used for the creation of the QinQ zone. | +| vrf-vxlan | integer | no | VNI for the zone VRF. | +| vxlan-port | integer | no | UDP port that should be used for the VXLAN tunnel (default 4789). | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_aplinfo.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_aplinfo.md new file mode 100644 index 00000000000..6a677b30dda --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_aplinfo.md @@ -0,0 +1,87 @@ +# POST /nodes/{node}/aplinfo + +Download appliance templates. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage where the template will be stored | +| template | string | yes | The template which will downloaded | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_apt_repositories.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_apt_repositories.md new file mode 100644 index 00000000000..1bc59c143ae --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_apt_repositories.md @@ -0,0 +1,99 @@ +# POST /nodes/{node}/apt/repositories + +Change the properties of a repository. Currently only allows enabling/disabling. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| index | integer | yes | Index within the file (starting from 0). | +| path | string | yes | Path to the containing file. | +| digest | string | no | Digest to detect modifications. | +| enabled | boolean | no | Whether the repository should be enabled or not. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_apt_update.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_apt_update.md new file mode 100644 index 00000000000..715caa2fe75 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_apt_update.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/apt/update + +This is used to resynchronize the package index files from their sources (apt-get update). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| notify | boolean | no | Send notification about new packages. | +| quiet | boolean | no | Only produces output suitable for logging, omitting progress indicators. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_fs_name.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_fs_name.md new file mode 100644 index 00000000000..f4684eee39d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_fs_name.md @@ -0,0 +1,98 @@ +# POST /nodes/{node}/ceph/fs/{name} + +Create a Ceph filesystem + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| name | string | no | The ceph filesystem name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| add-storage | boolean | no | Configure the created CephFS as storage for this cluster. | +| pg_num | integer | no | Number of placement groups for the backing data pool. The metadata pool will use a quarter of this. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_init.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_init.md new file mode 100644 index 00000000000..01848e15196 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_init.md @@ -0,0 +1,129 @@ +# POST /nodes/{node}/ceph/init + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cluster-network | string | no | Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it | +| disable_cephx | boolean | no | Disable cephx authentication. WARNING: cephx is a security feature protecting against man-in-the-middle attacks. Only consider disabling cephx if your network is private! | +| min_size | integer | no | Minimum number of available replicas per object to allow I/O | +| network | string | no | Use specific network for all ceph related traffic | +| pg_bits | integer | no | Placement group bits, used to specify the default number of placement groups. Depreacted. This setting was deprecated in recent Ceph versions. | +| size | integer | no | Targeted number of replicas per object | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mds_name.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mds_name.md new file mode 100644 index 00000000000..4cc4c4bb375 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mds_name.md @@ -0,0 +1,89 @@ +# POST /nodes/{node}/ceph/mds/{name} + +Create Ceph Metadata Server (MDS) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| name | string | no | The ID for the mds, when omitted the same as the nodename | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| hotstandby | boolean | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mgr_id.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mgr_id.md new file mode 100644 index 00000000000..12f878a7813 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mgr_id.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/ceph/mgr/{id} + +Create Ceph Manager + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| id | string | no | The ID for the manager, when omitted the same as the nodename. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mon_monid.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mon_monid.md new file mode 100644 index 00000000000..76fb1e554b8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_mon_monid.md @@ -0,0 +1,89 @@ +# POST /nodes/{node}/ceph/mon/{monid} + +Create a Ceph Monitor. Also auto-creates a Manager for the first monitor. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| monid | string | no | The ID for the monitor, when omitted the same as the nodename. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| mon-address | string | no | Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd.md new file mode 100644 index 00000000000..8ab69bd858d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd.md @@ -0,0 +1,116 @@ +# POST /nodes/{node}/ceph/osd + +Create OSD + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dev | string | yes | Block device name. | +| crush-device-class | string | no | Set the device class of the OSD in crush. | +| db_dev | string | no | Block device name for block.db. | +| db_dev_size | number | no | Size in GiB for block.db. | +| encrypted | boolean | no | Enables encryption of the OSD. | +| osds-per-device | integer | no | OSD services per physical device. Only useful for fast NVMe devices to utilize their performance better. Mutually exclusive with 'db_dev' and 'wal_dev'. | +| wal_dev | string | no | Block device name for block.wal. | +| wal_dev_size | number | no | Size in GiB for block.wal. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_in.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_in.md new file mode 100644 index 00000000000..0be9dce5993 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_in.md @@ -0,0 +1,77 @@ +# POST /nodes/{node}/ceph/osd/{osdid}/in + +ceph osd in + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_out.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_out.md new file mode 100644 index 00000000000..af1419233c1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_out.md @@ -0,0 +1,77 @@ +# POST /nodes/{node}/ceph/osd/{osdid}/out + +ceph osd out + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_scrub.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_scrub.md new file mode 100644 index 00000000000..e0c712d46b7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_osd_osdid_scrub.md @@ -0,0 +1,86 @@ +# POST /nodes/{node}/ceph/osd/{osdid}/scrub + +Instruct the OSD to scrub. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| osdid | integer | yes | OSD ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| deep | boolean | no | If set, instructs a deep scrub instead of a normal one. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_pool.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_pool.md new file mode 100644 index 00000000000..57055554671 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_pool.md @@ -0,0 +1,217 @@ +# POST /nodes/{node}/ceph/pool + +Create Ceph pool + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| add_storages | boolean | no | 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). | +| application | string | no | The application of the pool. | +| crush_rule | string | no | The rule to use for mapping object placement in the cluster. | +| erasure-coding | string | no | 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. | +| min_size | integer | no | Minimum number of replicas per object | +| pg_autoscale_mode | string | no | The automatic PG scaling mode of the pool. | +| pg_num | integer | no | Number of placement groups. | +| pg_num_min | integer | no | Minimal number of placement groups. | +| size | integer | no | Number of replicas per object | +| target_size | string | no | The estimated target size of the pool for the PG autoscaler. | +| target_size_ratio | number | no | The estimated target ratio of the pool for the PG autoscaler. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_restart.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_restart.md new file mode 100644 index 00000000000..c4203fc43d5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_restart.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/ceph/restart + +Restart ceph services. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| service | string | no | Ceph service name. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_start.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_start.md new file mode 100644 index 00000000000..8f1f3207a3a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_start.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/ceph/start + +Start ceph services. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| service | string | no | Ceph service name. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_stop.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_stop.md new file mode 100644 index 00000000000..396590bba04 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_ceph_stop.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/ceph/stop + +Stop ceph services. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| service | string | no | Ceph service name. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_certificates_acme_certificate.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_certificates_acme_certificate.md new file mode 100644 index 00000000000..41a1f297e58 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_certificates_acme_certificate.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/certificates/acme/certificate + +Order a new certificate from ACME-compatible CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Overwrite existing custom certificate. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_certificates_custom.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_certificates_custom.md new file mode 100644 index 00000000000..24ff4b89240 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_certificates_custom.md @@ -0,0 +1,221 @@ +# POST /nodes/{node}/certificates/custom + +Upload or update custom certificate chain and key. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| certificates | string | yes | PEM encoded certificate (chain). | +| force | boolean | no | Overwrite existing custom or ACME certificate files. | +| key | string | no | PEM encoded private key. | +| restart | boolean | no | Restart pveproxy. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_directory.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_directory.md new file mode 100644 index 00000000000..8e4a114ae13 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_directory.md @@ -0,0 +1,107 @@ +# POST /nodes/{node}/disks/directory + +Create a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| device | string | yes | The block device you want to create the filesystem on. | +| name | string | yes | The storage identifier. | +| add_storage | boolean | no | Configure storage using the directory. | +| filesystem | string | no | The desired filesystem. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_initgpt.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_initgpt.md new file mode 100644 index 00000000000..956f1dcd938 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_initgpt.md @@ -0,0 +1,86 @@ +# POST /nodes/{node}/disks/initgpt + +Initialize Disk with GPT + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | Block device name | +| uuid | string | no | UUID for the GPT table | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_lvm.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_lvm.md new file mode 100644 index 00000000000..2c52f713a51 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_lvm.md @@ -0,0 +1,96 @@ +# POST /nodes/{node}/disks/lvm + +Create an LVM Volume Group + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| device | string | yes | The block device you want to create the volume group on | +| name | string | yes | The storage identifier. | +| add_storage | boolean | no | Configure storage using the Volume Group | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_lvmthin.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_lvmthin.md new file mode 100644 index 00000000000..3d8ad09c5a9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_lvmthin.md @@ -0,0 +1,96 @@ +# POST /nodes/{node}/disks/lvmthin + +Create an LVM thinpool + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| device | string | yes | The block device you want to create the thinpool on. | +| name | string | yes | The storage identifier. | +| add_storage | boolean | no | Configure storage using the thinpool. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_zfs.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_zfs.md new file mode 100644 index 00000000000..30a1ca34644 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_disks_zfs.md @@ -0,0 +1,157 @@ +# POST /nodes/{node}/disks/zfs + +Create a ZFS pool. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| devices | string | yes | The block devices you want to create the zpool on. | +| name | string | yes | The storage identifier. | +| raidlevel | string | yes | The RAID level to use. | +| add_storage | boolean | no | Configure storage using the zpool. | +| ashift | integer | no | Pool sector size exponent. | +| compression | string | no | The compression algorithm to use. | +| draid-config | string | no | | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "Requires additionally 'Datastore.Allocate' on /storage when setting 'add_storage'" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_execute.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_execute.md new file mode 100644 index 00000000000..88d032f5f22 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_execute.md @@ -0,0 +1,69 @@ +# POST /nodes/{node}/execute + +Execute multiple commands in order, root only. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| commands | string | yes | JSON encoded array of commands. | + +## Returns + +```json +{ + "items": { + "properties": {}, + "type": "object" + }, + "type": "array" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_firewall_rules.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_firewall_rules.md new file mode 100644 index 00000000000..24e0460cf2c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_firewall_rules.md @@ -0,0 +1,209 @@ +# POST /nodes/{node}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_hosts.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_hosts.md new file mode 100644 index 00000000000..73be1f0ad97 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_hosts.md @@ -0,0 +1,86 @@ +# POST /nodes/{node}/hosts + +Write /etc/hosts. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| data | string | yes | The target content of /etc/hosts. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc.md new file mode 100644 index 00000000000..ba6655cebf8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc.md @@ -0,0 +1,780 @@ +# POST /nodes/{node}/lxc + +Create or restore a container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ostemplate | string | yes | The OS template or backup file. | +| vmid | integer | yes | The (unique) ID of the VM. | +| arch | string | no | OS architecture type. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| cmode | string | no | 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). | +| console | boolean | no | Attach a console device (/dev/console) to the container. | +| cores | integer | no | The number of cores assigned to the container. A container can use all available cores by default. | +| cpulimit | number | no | Limit of CPU usage. NOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit. | +| cpuunits | integer | no | CPU weight for a container, will be clamped to [1, 10000] in cgroup v2. | +| debug | boolean | no | Try to be more verbose. For now this only enables debug log-level on start. | +| description | string | no | Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file. | +| dev[n] | string | no | Device to pass through to the container | +| entrypoint | string | no | Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH. | +| env | string | no | The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config. | +| features | string | no | Allow containers access to advanced features. | +| force | boolean | no | Allow to overwrite existing container. | +| ha-managed | boolean | no | Add the CT as a HA resource after it was created. | +| hookscript | string | no | Script that will be executed during various steps in the containers lifetime. | +| hostname | string | no | Set a host name for the container. | +| ignore-unpack-errors | boolean | no | Ignore errors when extracting the template. | +| lock | string | no | Lock/unlock the container. | +| memory | integer | no | Amount of RAM for the container in MB. | +| mp[n] | string | no | Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. | +| nameserver | string | no | Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| net[n] | string | no | Specifies network interfaces for the container. | +| onboot | boolean | no | Specifies whether a container will be started during system bootup. | +| ostype | string | no | 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. | +| password | string | no | Sets root password inside container. | +| pool | string | no | Add the VM to the specified pool. | +| protection | boolean | no | Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation. | +| restore | boolean | no | Mark this as restore task. | +| rootfs | string | no | Use volume as container root. | +| searchdomain | string | no | Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| ssh-public-keys | string | no | Setup public SSH keys (one key per line, OpenSSH format). | +| start | boolean | no | Start the CT after its creation finished successfully. | +| startup | string | no | 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. | +| storage | string | no | Default Storage. | +| swap | integer | no | Amount of SWAP for the container in MB. | +| tags | string | no | Tags of the Container. This is only meta information. | +| template | boolean | no | Enable/disable Template. | +| timezone | string | no | 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 | +| tty | integer | no | Specify the number of tty available to the container | +| unique | boolean | no | Assign a unique random ethernet address. | +| unprivileged | boolean | no | 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.) | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_clone.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_clone.md new file mode 100644 index 00000000000..a050e89a199 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_clone.md @@ -0,0 +1,201 @@ +# POST /nodes/{node}/lxc/{vmid}/clone + +Create a container clone/copy + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| newid | integer | yes | VMID for the clone. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| description | string | no | Description for the new CT. | +| full | boolean | no | 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. | +| hostname | string | no | Set a hostname for the new CT. | +| pool | string | no | Add the new CT to the specified pool. | +| snapname | string | no | The name of the snapshot. | +| storage | string | no | Target storage for full clone. | +| target | string | no | Target node. Only allowed if the original VM is on shared storage. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_aliases.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_aliases.md new file mode 100644 index 00000000000..02790935e55 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_aliases.md @@ -0,0 +1,101 @@ +# POST /nodes/{node}/lxc/{vmid}/firewall/aliases + +Create IP or Network Alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | Alias name. | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_ipset.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_ipset.md new file mode 100644 index 00000000000..057b537bdb3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_ipset.md @@ -0,0 +1,111 @@ +# POST /nodes/{node}/lxc/{vmid}/firewall/ipset + +Create new IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_ipset_name.md new file mode 100644 index 00000000000..b570a831e8e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_ipset_name.md @@ -0,0 +1,107 @@ +# POST /nodes/{node}/lxc/{vmid}/firewall/ipset/{name} + +Add IP or Network to IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_rules.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_rules.md new file mode 100644 index 00000000000..96369ebd16d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_firewall_rules.md @@ -0,0 +1,218 @@ +# POST /nodes/{node}/lxc/{vmid}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_migrate.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_migrate.md new file mode 100644 index 00000000000..0122cbef951 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_migrate.md @@ -0,0 +1,129 @@ +# POST /nodes/{node}/lxc/{vmid}/migrate + +Migrate the container to another node. Creates a new migration task. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| online | boolean | no | Use online/live migration. | +| restart | boolean | no | Use restart migration | +| target-storage | string | no | 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. | +| timeout | integer | no | Timeout in seconds for shutdown for restart migration | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_move_volume.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_move_volume.md new file mode 100644 index 00000000000..0163ec3d1ef --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_move_volume.md @@ -0,0 +1,1176 @@ +# POST /nodes/{node}/lxc/{vmid}/move_volume + +Move a rootfs-/mp-volume to a different storage or to a different container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| volume | string | yes | Volume which will be moved. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | Delete the original volume after successful copy. By default the original is kept as an unused volume entry. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 " . "digest. This can be used to prevent concurrent modifications. | +| storage | string | no | Target Storage. | +| target-digest | string | no | Prevent changes if current configuration file of the target " . "container has a different SHA1 digest. This can be used to prevent " . "concurrent modifications. | +| target-vmid | integer | no | The (unique) ID of the VM. | +| target-volume | string | no | The config key the volume will be moved to. Default is the source volume key. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_mtunnel.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_mtunnel.md new file mode 100644 index 00000000000..5d40e0fe0c5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_mtunnel.md @@ -0,0 +1,140 @@ +# POST /nodes/{node}/lxc/{vmid}/mtunnel + +Migration tunnel endpoint - only for internal use by CT migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| bridges | string | no | List of network bridges to check availability. Will be checked again for actually used bridges during migration. | +| storages | string | no | List of storages to check permission and availability. Will be checked again for all actually used storages during migration. | + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "socket": { + "type": "string" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_remote_migrate.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_remote_migrate.md new file mode 100644 index 00000000000..8ce98d21b7c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_remote_migrate.md @@ -0,0 +1,154 @@ +# POST /nodes/{node}/lxc/{vmid}/remote_migrate + +Migrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target-bridge | string | yes | 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. | +| target-endpoint | string | yes | Remote target endpoint | +| target-storage | string | yes | 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. | +| bwlimit | number | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | 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. | +| online | boolean | no | Use online/live migration. | +| restart | boolean | no | Use restart migration | +| target-vmid | integer | no | The (unique) ID of the VM. | +| timeout | integer | no | Timeout in seconds for shutdown for restart migration | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_snapshot.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_snapshot.md new file mode 100644 index 00000000000..2f8ac530e2e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_snapshot.md @@ -0,0 +1,98 @@ +# POST /nodes/{node}/lxc/{vmid}/snapshot + +Snapshot a container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| snapname | string | yes | The name of the snapshot. | +| description | string | no | A textual description or comment. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_snapshot_snapname_rollback.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_snapshot_snapname_rollback.md new file mode 100644 index 00000000000..26bd9d7f0fb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_snapshot_snapname_rollback.md @@ -0,0 +1,105 @@ +# POST /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback + +Rollback LXC state to specified snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| start | boolean | no | Whether the container should get started after rolling back successfully | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_spiceproxy.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_spiceproxy.md new file mode 100644 index 00000000000..cbf4ab7cfc2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_spiceproxy.md @@ -0,0 +1,125 @@ +# POST /nodes/{node}/lxc/{vmid}/spiceproxy + +Returns a SPICE configuration to connect to the CT. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| proxy | string | no | 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). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_reboot.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_reboot.md new file mode 100644 index 00000000000..daa6750c612 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_reboot.md @@ -0,0 +1,89 @@ +# POST /nodes/{node}/lxc/{vmid}/status/reboot + +Reboot the container by shutting it down, and starting it again. Applies pending changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeout | integer | no | Wait maximal timeout seconds for the shutdown. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_resume.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_resume.md new file mode 100644 index 00000000000..91e93ef52f0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_resume.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/lxc/{vmid}/status/resume + +Resume the container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_shutdown.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_shutdown.md new file mode 100644 index 00000000000..2463e1f060f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_shutdown.md @@ -0,0 +1,98 @@ +# POST /nodes/{node}/lxc/{vmid}/status/shutdown + +Shutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| forceStop | boolean | no | Make sure the Container stops. | +| timeout | integer | no | Wait maximal timeout seconds. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_start.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_start.md new file mode 100644 index 00000000000..327ae5632e5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_start.md @@ -0,0 +1,96 @@ +# POST /nodes/{node}/lxc/{vmid}/status/start + +Start the container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| debug | boolean | no | If set, enables very verbose debug log-level on start. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_stop.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_stop.md new file mode 100644 index 00000000000..f6feb913b90 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_stop.md @@ -0,0 +1,96 @@ +# POST /nodes/{node}/lxc/{vmid}/status/stop + +Stop the container. This will abruptly stop all processes running in the container. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| overrule-shutdown | boolean | no | Try to abort active 'vzshutdown' tasks before stopping. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_suspend.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_suspend.md new file mode 100644 index 00000000000..ba0a879715e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_status_suspend.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/lxc/{vmid}/status/suspend + +Suspend the container. This is experimental. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_template.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_template.md new file mode 100644 index 00000000000..578ff00dcc1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_template.md @@ -0,0 +1,82 @@ +# POST /nodes/{node}/lxc/{vmid}/template + +Create a Template. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description": "You need 'VM.Allocate' permissions on /vms/{vmid}" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_termproxy.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_termproxy.md new file mode 100644 index 00000000000..ae714e89508 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_termproxy.md @@ -0,0 +1,107 @@ +# POST /nodes/{node}/lxc/{vmid}/termproxy + +Creates a TCP proxy connection. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "port": { + "type": "integer" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + }, + "user": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_vncproxy.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_vncproxy.md new file mode 100644 index 00000000000..5aa98aa9cf7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_lxc_vmid_vncproxy.md @@ -0,0 +1,149 @@ +# POST /nodes/{node}/lxc/{vmid}/vncproxy + +Creates a TCP VNC proxy connections. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| height | integer | no | sets the height of the console in pixels. | +| websocket | boolean | no | use websocket instead of standard VNC. | +| width | integer | no | sets the width of the console in pixels. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_migrateall.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_migrateall.md new file mode 100644 index 00000000000..714dd9ffd05 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_migrateall.md @@ -0,0 +1,102 @@ +# POST /nodes/{node}/migrateall + +Migrate all VMs and Containers. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| max-workers | integer | no | Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set! | +| maxworkers | integer | no | 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. | +| vms | string | no | Only consider Guests with these IDs. | +| with-local-disks | boolean | no | Enable live storage migration for local disk | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.Migrate' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_network.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_network.md new file mode 100644 index 00000000000..27fa9171281 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_network.md @@ -0,0 +1,325 @@ +# POST /nodes/{node}/network + +Create network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| type | string | yes | Network interface type | +| address | string | no | IP address. | +| address6 | string | no | IP address. | +| autostart | boolean | no | Automatically start interface on boot. | +| bond_mode | string | no | Bonding mode. | +| bond_xmit_hash_policy | string | no | Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. | +| bond-primary | string | no | Specify the primary interface for active-backup bond. | +| bridge_ports | string | no | Specify the interfaces you want to add to your bridge. | +| bridge_vids | string | no | Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware. | +| bridge_vlan_aware | boolean | no | Enable bridge vlan support. | +| cidr | string | no | IPv4 CIDR. | +| cidr6 | string | no | IPv6 CIDR. | +| comments | string | no | Comments | +| comments6 | string | no | Comments | +| gateway | string | no | Default gateway address. | +| gateway6 | string | no | Default ipv6 gateway address. | +| mtu | integer | no | MTU. | +| netmask | string | no | Network mask. | +| netmask6 | integer | no | Network mask. | +| ovs_bonds | string | no | Specify the interfaces used by the bonding device. | +| ovs_bridge | string | no | The OVS bridge associated with a OVS port. This is required when you create an OVS port. | +| ovs_options | string | no | OVS interface options. | +| ovs_ports | string | no | Specify the interfaces you want to add to your bridge. | +| ovs_tag | integer | no | Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond) | +| slaves | string | no | Specify the interfaces used by the bonding device. | +| vlan-id | integer | no | vlan-id for a custom named vlan interface (ifupdown2 only). | +| vlan-raw-device | string | no | Specify the raw interface for the vlan interface. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu.md new file mode 100644 index 00000000000..0bf7d24ff3a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu.md @@ -0,0 +1,2617 @@ +# POST /nodes/{node}/qemu + +Create or restore a virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vmid | integer | yes | The (unique) ID of the VM. | +| acpi | boolean | no | Enable/disable ACPI. | +| affinity | string | no | List of host cores used to execute guest processes, for example: 0,5,8-11 | +| agent | string | no | Enable/disable communication with the QEMU Guest Agent and its properties. | +| allow-ksm | boolean | no | Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging). | +| amd-sev | string | no | Secure Encrypted Virtualization (SEV) features by AMD CPUs | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | +| archive | string | no | 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. | +| args | string | no | Arbitrary arguments passed to kvm. | +| audio0 | string | no | Configure a audio device, useful in combination with QXL/Spice. | +| autostart | boolean | no | Automatic restart after crash (currently ignored). | +| balloon | integer | no | 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. | +| bios | string | no | Select BIOS implementation. | +| boot | string | no | Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated. | +| bootdisk | string | no | Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| cdrom | string | no | This is an alias for option -ide2 | +| cicustom | string | no | cloud-init: Specify custom files to replace the automatically generated ones at start. | +| cipassword | string | no | 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. | +| citype | string | no | 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. | +| ciupgrade | boolean | no | cloud-init: do an automatic package upgrade after the first boot. | +| ciuser | string | no | cloud-init: User name to change ssh keys and password for instead of the image's configured default user. | +| cores | integer | no | The number of cores per socket. | +| cpu | string | no | Emulated CPU type. | +| cpulimit | number | no | Limit of CPU usage. | +| cpuunits | integer | no | CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2. | +| description | string | no | Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file. | +| efidisk0 | string | no | 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. | +| force | boolean | no | Allow to overwrite existing VM. | +| freeze | boolean | no | Freeze CPU at startup (use 'c' monitor command to start execution). | +| ha-managed | boolean | no | Add the VM as a HA resource after it was created. | +| hookscript | string | no | Script that will be executed during various steps in the vms lifetime. | +| hostpci[n] | string | no | Map host PCI devices into guest. | +| hotplug | string | no | 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. | +| hugepages | string | no | Enables hugepages memory. Sets 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. | +| ide[n] | string | no | 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. | +| import-working-storage | string | no | A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage. | +| intel-tdx | string | no | Trusted Domain Extension (TDX) features by Intel CPUs | +| ipconfig[n] | string | no | cloud-init: Specify IP addresses and gateways for the corresponding interface. IP addresses use CIDR notation, gateways are optional but need an IP of the same type specified. The special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit gateway should be provided. For IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires cloud-init 19.4 or newer. If cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using dhcp on IPv4. | +| ivshmem | string | no | Inter-VM shared memory. Useful for direct communication between VMs, or to the host. | +| keephugepages | boolean | no | Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts. | +| keyboard | string | no | Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. | +| kvm | boolean | no | Enable/disable KVM hardware virtualization. | +| live-restore | boolean | no | Start the VM immediately while importing or restoring in the background. | +| localtime | boolean | no | Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS. | +| lock | string | no | Lock/unlock the VM. | +| machine | string | no | Specify the QEMU machine. | +| memory | string | no | Memory properties. | +| migrate_downtime | number | no | 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). | +| migrate_speed | integer | no | Set maximum speed (in MB/s) for migrations. Value 0 is no limit. | +| name | string | no | Set a name for the VM. Only used on the configuration web interface. | +| nameserver | string | no | 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. | +| net[n] | string | no | Specify network devices. | +| numa | boolean | no | Enable/disable NUMA. | +| numa[n] | string | no | NUMA topology. | +| onboot | boolean | no | Specifies whether a VM will be started during system bootup. | +| ostype | string | no | Specify guest operating system. | +| parallel[n] | string | no | Map host parallel devices (n is 0 to 2). | +| pool | string | no | Add the VM to the specified pool. | +| protection | boolean | no | Sets the protection flag of the VM. This will disable the remove VM and remove disk operations. | +| reboot | boolean | no | Allow reboot. If set to '0' the VM exit on reboot. | +| rng0 | string | no | Configure a VirtIO-based Random Number Generator. | +| sata[n] | string | no | 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. | +| scsi[n] | string | no | 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. | +| scsihw | string | no | SCSI controller model | +| searchdomain | string | no | 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. | +| serial[n] | string | no | Create a serial device inside the VM (n is 0 to 3) | +| shares | integer | no | 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. | +| smbios1 | string | no | Specify SMBIOS type 1 fields. | +| smp | integer | no | The number of CPUs. Please use option -sockets instead. | +| sockets | integer | no | The number of CPU sockets. | +| spice_enhancements | string | no | Configure additional enhancements for SPICE. | +| sshkeys | string | no | cloud-init: Setup public SSH keys (one key per line, OpenSSH format). | +| start | boolean | no | Start VM after it was created successfully. | +| startdate | string | no | 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'. | +| startup | string | no | 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. | +| storage | string | no | Default storage. | +| tablet | boolean | no | Enable/disable the USB tablet device. | +| tags | string | no | Tags of the VM. This is only meta information. | +| tdf | boolean | no | Enable/disable time drift fix. | +| template | boolean | no | Enable/disable Template. | +| tpmstate0 | string | no | 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. | +| unique | boolean | no | Assign a unique random ethernet address. | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | +| usb[n] | string | no | 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). | +| vcpus | integer | no | Number of hotplugged vcpus. | +| vga | string | no | Configure the VGA hardware. | +| virtio[n] | string | no | 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. | +| virtiofs[n] | string | no | Configuration for sharing a directory between host and guest using Virtio-fs. | +| vmgenid | string | no | Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly. | +| vmstatestorage | string | no | Default storage for VM state volumes/files. | +| watchdog | string | no | Create a virtual hardware watchdog device. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent.md new file mode 100644 index 00000000000..e6176a4d523 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent.md @@ -0,0 +1,116 @@ +# POST /nodes/{node}/qemu/{vmid}/agent + +Execute QEMU Guest Agent commands. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | string | yes | The QGA command. | + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_exec.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_exec.md new file mode 100644 index 00000000000..06d0bc6886b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_exec.md @@ -0,0 +1,111 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/exec + +Executes the given command in the vm via the guest-agent and returns an object with the pid. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | array | yes | The command as a list of program + arguments. | +| input-data | string | no | Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'. | + +## Returns + +```json +{ + "properties": { + "pid": { + "description": "The PID of the process started by the guest-agent.", + "type": "integer" + } + }, + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_file_write.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_file_write.md new file mode 100644 index 00000000000..86562d5f4c6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_file_write.md @@ -0,0 +1,108 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/file-write + +Writes the given file via guest agent. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | yes | The content to write into the file. | +| file | string | yes | The path to the file. | +| encode | boolean | no | If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileWrite", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_freeze.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_freeze.md new file mode 100644 index 00000000000..db0bd18d2a2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_freeze.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze + +Execute fsfreeze-freeze. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_status.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_status.md new file mode 100644 index 00000000000..80ceae266de --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_status.md @@ -0,0 +1,90 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-status + +Execute fsfreeze-status. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_thaw.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_thaw.md new file mode 100644 index 00000000000..fd9875c2828 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_thaw.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw + +Execute fsfreeze-thaw. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fstrim.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fstrim.md new file mode 100644 index 00000000000..a46a43ae143 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_fstrim.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/fstrim + +Execute fstrim. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.FileSystemMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_ping.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_ping.md new file mode 100644 index 00000000000..397f620e943 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_ping.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/ping + +Execute ping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Audit", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_set_user_password.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_set_user_password.md new file mode 100644 index 00000000000..24a563ac46d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_set_user_password.md @@ -0,0 +1,105 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/set-user-password + +Sets the password for the given user to the given password + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | The new password. | +| username | string | yes | The user to set the password for. | +| crypted | boolean | no | set to 1 if the password has already been passed through crypt() | + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.GuestAgent.Unrestricted" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_shutdown.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_shutdown.md new file mode 100644 index 00000000000..49eeaf089c7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_shutdown.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/shutdown + +Execute shutdown. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_disk.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_disk.md new file mode 100644 index 00000000000..25dd79c8d41 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_disk.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/suspend-disk + +Execute suspend-disk. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_hybrid.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_hybrid.md new file mode 100644 index 00000000000..46c981b3ee1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_hybrid.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/suspend-hybrid + +Execute suspend-hybrid. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_ram.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_ram.md new file mode 100644 index 00000000000..80e0f5c656a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_agent_suspend_ram.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/agent/suspend-ram + +Execute suspend-ram. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "Returns an object with a single `result` property.", + "type": "object" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt", + "VM.GuestAgent.Unrestricted" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_clone.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_clone.md new file mode 100644 index 00000000000..3104c638878 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_clone.md @@ -0,0 +1,212 @@ +# POST /nodes/{node}/qemu/{vmid}/clone + +Create a copy of virtual machine/template. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| newid | integer | yes | VMID for the clone. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| description | string | no | Description for the new VM. | +| format | string | no | Target format for file storage. Only valid for full clone. | +| full | boolean | no | 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. | +| name | string | no | Set a name for the new VM. | +| pool | string | no | Add the new VM to the specified pool. | +| snapname | string | no | The name of the snapshot. | +| storage | string | no | Target storage for full clone. | +| target | string | no | Target node. Only allowed if the original VM is on shared storage. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_config.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_config.md new file mode 100644 index 00000000000..4944c680b4c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_config.md @@ -0,0 +1,2622 @@ +# POST /nodes/{node}/qemu/{vmid}/config + +Set virtual machine options (asynchronous API). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acpi | boolean | no | Enable/disable ACPI. | +| affinity | string | no | List of host cores used to execute guest processes, for example: 0,5,8-11 | +| agent | string | no | Enable/disable communication with the QEMU Guest Agent and its properties. | +| allow-ksm | boolean | no | Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging). | +| amd-sev | string | no | Secure Encrypted Virtualization (SEV) features by AMD CPUs | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | +| args | string | no | Arbitrary arguments passed to kvm. | +| audio0 | string | no | Configure a audio device, useful in combination with QXL/Spice. | +| autostart | boolean | no | Automatic restart after crash (currently ignored). | +| background_delay | integer | no | Time to wait for the task to finish. We return 'null' if the task finish within that time. | +| balloon | integer | no | 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. | +| bios | string | no | Select BIOS implementation. | +| boot | string | no | Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated. | +| bootdisk | string | no | Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead. | +| cdrom | string | no | This is an alias for option -ide2 | +| cicustom | string | no | cloud-init: Specify custom files to replace the automatically generated ones at start. | +| cipassword | string | no | 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. | +| citype | string | no | 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. | +| ciupgrade | boolean | no | cloud-init: do an automatic package upgrade after the first boot. | +| ciuser | string | no | cloud-init: User name to change ssh keys and password for instead of the image's configured default user. | +| cores | integer | no | The number of cores per socket. | +| cpu | string | no | Emulated CPU type. | +| cpulimit | number | no | Limit of CPU usage. | +| cpuunits | integer | no | CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| efidisk0 | string | no | 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. | +| force | boolean | no | 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. | +| freeze | boolean | no | Freeze CPU at startup (use 'c' monitor command to start execution). | +| hookscript | string | no | Script that will be executed during various steps in the vms lifetime. | +| hostpci[n] | string | no | Map host PCI devices into guest. | +| hotplug | string | no | 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. | +| hugepages | string | no | Enables hugepages memory. Sets 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. | +| ide[n] | string | no | 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. | +| import-working-storage | string | no | A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage. | +| intel-tdx | string | no | Trusted Domain Extension (TDX) features by Intel CPUs | +| ipconfig[n] | string | no | cloud-init: Specify IP addresses and gateways for the corresponding interface. IP addresses use CIDR notation, gateways are optional but need an IP of the same type specified. The special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit gateway should be provided. For IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires cloud-init 19.4 or newer. If cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using dhcp on IPv4. | +| ivshmem | string | no | Inter-VM shared memory. Useful for direct communication between VMs, or to the host. | +| keephugepages | boolean | no | Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts. | +| keyboard | string | no | Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. | +| kvm | boolean | no | Enable/disable KVM hardware virtualization. | +| localtime | boolean | no | Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS. | +| lock | string | no | Lock/unlock the VM. | +| machine | string | no | Specify the QEMU machine. | +| memory | string | no | Memory properties. | +| migrate_downtime | number | no | 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). | +| migrate_speed | integer | no | Set maximum speed (in MB/s) for migrations. Value 0 is no limit. | +| name | string | no | Set a name for the VM. Only used on the configuration web interface. | +| nameserver | string | no | 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. | +| net[n] | string | no | Specify network devices. | +| numa | boolean | no | Enable/disable NUMA. | +| numa[n] | string | no | NUMA topology. | +| onboot | boolean | no | Specifies whether a VM will be started during system bootup. | +| ostype | string | no | Specify guest operating system. | +| parallel[n] | string | no | Map host parallel devices (n is 0 to 2). | +| protection | boolean | no | Sets the protection flag of the VM. This will disable the remove VM and remove disk operations. | +| reboot | boolean | no | Allow reboot. If set to '0' the VM exit on reboot. | +| revert | string | no | Revert a pending change. | +| rng0 | string | no | Configure a VirtIO-based Random Number Generator. | +| sata[n] | string | no | 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. | +| scsi[n] | string | no | 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. | +| scsihw | string | no | SCSI controller model | +| searchdomain | string | no | 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. | +| serial[n] | string | no | Create a serial device inside the VM (n is 0 to 3) | +| shares | integer | no | 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. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| smbios1 | string | no | Specify SMBIOS type 1 fields. | +| smp | integer | no | The number of CPUs. Please use option -sockets instead. | +| sockets | integer | no | The number of CPU sockets. | +| spice_enhancements | string | no | Configure additional enhancements for SPICE. | +| sshkeys | string | no | cloud-init: Setup public SSH keys (one key per line, OpenSSH format). | +| startdate | string | no | 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'. | +| startup | string | no | 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. | +| tablet | boolean | no | Enable/disable the USB tablet device. | +| tags | string | no | Tags of the VM. This is only meta information. | +| tdf | boolean | no | Enable/disable time drift fix. | +| template | boolean | no | Enable/disable Template. | +| tpmstate0 | string | no | 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. | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | +| usb[n] | string | no | 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). | +| vcpus | integer | no | Number of hotplugged vcpus. | +| vga | string | no | Configure the VGA hardware. | +| virtio[n] | string | no | 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. | +| virtiofs[n] | string | no | Configuration for sharing a directory between host and guest using Virtio-fs. | +| vmgenid | string | no | Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly. | +| vmstatestorage | string | no | Default storage for VM state volumes/files. | +| watchdog | string | no | Create a virtual hardware watchdog device. | + +## Returns + +```json +{ + "optional": 1, + "type": "string" +} +``` + +## Permissions + +```json +{ + "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 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_dbus_vmstate.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_dbus_vmstate.md new file mode 100644 index 00000000000..771f3865433 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_dbus_vmstate.md @@ -0,0 +1,90 @@ +# POST /nodes/{node}/qemu/{vmid}/dbus-vmstate + +Control the dbus-vmstate helper for a given running VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Action to perform on the DBus VMState helper. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_aliases.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_aliases.md new file mode 100644 index 00000000000..35fe85790c4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_aliases.md @@ -0,0 +1,101 @@ +# POST /nodes/{node}/qemu/{vmid}/firewall/aliases + +Create IP or Network Alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | Alias name. | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_ipset.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_ipset.md new file mode 100644 index 00000000000..66440429fb8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_ipset.md @@ -0,0 +1,111 @@ +# POST /nodes/{node}/qemu/{vmid}/firewall/ipset + +Create new IPSet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_ipset_name.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_ipset_name.md new file mode 100644 index 00000000000..f39939a426c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_ipset_name.md @@ -0,0 +1,107 @@ +# POST /nodes/{node}/qemu/{vmid}/firewall/ipset/{name} + +Add IP or Network to IPSet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_rules.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_rules.md new file mode 100644 index 00000000000..cb4d2ca09fa --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_firewall_rules.md @@ -0,0 +1,218 @@ +# POST /nodes/{node}/qemu/{vmid}/firewall/rules + +Create new rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | yes | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| type | string | yes | Rule type. | +| comment | string | no | Descriptive comment. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| pos | integer | no | Update rule at position . | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_migrate.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_migrate.md new file mode 100644 index 00000000000..0c11131547b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_migrate.md @@ -0,0 +1,154 @@ +# POST /nodes/{node}/qemu/{vmid}/migrate + +Migrate virtual machine. Creates a new migration task. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target node. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| force | boolean | no | Allow to migrate VMs which use local devices. Only root may use this option. | +| migration_network | string | no | CIDR of the (sub) network that is used for migration. | +| migration_type | string | no | Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. | +| online | boolean | no | Use online/live migration if VM is running. Ignored if VM is stopped. | +| targetstorage | string | no | 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. | +| with-conntrack-state | boolean | no | Whether to migrate conntrack entries for running VMs. | +| with-local-disks | boolean | no | Enable live storage migration for local disk | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_monitor.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_monitor.md new file mode 100644 index 00000000000..abc7bc0eb63 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_monitor.md @@ -0,0 +1,95 @@ +# POST /nodes/{node}/qemu/{vmid}/monitor + +Execute QEMU monitor commands. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | string | yes | The monitor command. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_move_disk.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_move_disk.md new file mode 100644 index 00000000000..2b16943caf7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_move_disk.md @@ -0,0 +1,793 @@ +# POST /nodes/{node}/qemu/{vmid}/move_disk + +Move volume to different storage or to a different VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | The disk you want to move. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | Delete the original disk after successful copy. By default the original disk is kept as unused disk. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| format | string | no | Target Format. | +| storage | string | no | Target storage. | +| target-digest | string | no | Prevent changes if the current config file of the target VM has a different SHA1 digest. This can be used to detect concurrent modifications. | +| target-disk | string | no | The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key. | +| target-vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_mtunnel.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_mtunnel.md new file mode 100644 index 00000000000..94565a8e240 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_mtunnel.md @@ -0,0 +1,140 @@ +# POST /nodes/{node}/qemu/{vmid}/mtunnel + +Migration tunnel endpoint - only for internal use by VM migration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| bridges | string | no | List of network bridges to check availability. Will be checked again for actually used bridges during migration. | +| storages | string | no | List of storages to check permission and availability. Will be checked again for all actually used storages during migration. | + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "socket": { + "type": "string" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_remote_migrate.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_remote_migrate.md new file mode 100644 index 00000000000..4916374c7b8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_remote_migrate.md @@ -0,0 +1,139 @@ +# POST /nodes/{node}/qemu/{vmid}/remote_migrate + +Migrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target-bridge | string | yes | 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. | +| target-endpoint | string | yes | Remote target endpoint | +| target-storage | string | yes | 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. | +| bwlimit | integer | no | Override I/O bandwidth limit (in KiB/s). | +| delete | boolean | no | 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. | +| online | boolean | no | Use online/live migration if VM is running. Ignored if VM is stopped. | +| target-vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Migrate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_snapshot.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_snapshot.md new file mode 100644 index 00000000000..fe41bc679e3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_snapshot.md @@ -0,0 +1,105 @@ +# POST /nodes/{node}/qemu/{vmid}/snapshot + +Snapshot a VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| snapname | string | yes | The name of the snapshot. | +| description | string | no | A textual description or comment. | +| vmstate | boolean | no | Save the vmstate | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_snapshot_snapname_rollback.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_snapshot_snapname_rollback.md new file mode 100644 index 00000000000..ec48286c70a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_snapshot_snapname_rollback.md @@ -0,0 +1,105 @@ +# POST /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback + +Rollback VM state to specified snapshot. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| start | boolean | no | Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.) | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot", + "VM.Snapshot.Rollback" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_spiceproxy.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_spiceproxy.md new file mode 100644 index 00000000000..cb6fab067da --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_spiceproxy.md @@ -0,0 +1,125 @@ +# POST /nodes/{node}/qemu/{vmid}/spiceproxy + +Returns a SPICE configuration to connect to the VM. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| proxy | string | no | 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). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_reboot.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_reboot.md new file mode 100644 index 00000000000..189ca55465d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_reboot.md @@ -0,0 +1,89 @@ +# POST /nodes/{node}/qemu/{vmid}/status/reboot + +Reboot the VM by shutting it down, and starting it again. Applies pending changes. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timeout | integer | no | Wait maximal timeout seconds for the shutdown. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_reset.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_reset.md new file mode 100644 index 00000000000..cbcc7bbf134 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_reset.md @@ -0,0 +1,88 @@ +# POST /nodes/{node}/qemu/{vmid}/status/reset + +Reset virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_resume.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_resume.md new file mode 100644 index 00000000000..dde7d4e8456 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_resume.md @@ -0,0 +1,94 @@ +# POST /nodes/{node}/qemu/{vmid}/status/resume + +Resume virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| nocheck | boolean | no | | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_shutdown.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_shutdown.md new file mode 100644 index 00000000000..6d13751a3d0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_shutdown.md @@ -0,0 +1,112 @@ +# POST /nodes/{node}/qemu/{vmid}/status/shutdown + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| forceStop | boolean | no | Make sure the VM stops. | +| keepActive | boolean | no | Do not deactivate storage volumes. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| timeout | integer | no | Wait maximal timeout seconds. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_start.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_start.md new file mode 100644 index 00000000000..39d59ab645c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_start.md @@ -0,0 +1,206 @@ +# POST /nodes/{node}/qemu/{vmid}/status/start + +Start virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force-cpu | string | no | Override QEMU's -cpu argument with the given string. | +| machine | string | no | Specify the QEMU machine. | +| migratedfrom | string | no | The cluster node name. | +| migration_network | string | no | CIDR of the (sub) network that is used for migration. | +| migration_type | string | no | Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. | +| nets-host-mtu | string | no | 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. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| stateuri | string | no | Some command save/restore state from this location. | +| targetstorage | string | no | 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. | +| timeout | integer | no | Wait maximal timeout seconds. | +| with-conntrack-state | boolean | no | Whether to migrate conntrack entries for running VMs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_stop.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_stop.md new file mode 100644 index 00000000000..9568c9b7f9f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_stop.md @@ -0,0 +1,120 @@ +# POST /nodes/{node}/qemu/{vmid}/status/stop + +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. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| keepActive | boolean | no | Do not deactivate storage volumes. | +| migratedfrom | string | no | The cluster node name. | +| overrule-shutdown | boolean | no | Try to abort active 'qmshutdown' tasks before stopping. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| timeout | integer | no | Wait maximal timeout seconds. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_suspend.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_suspend.md new file mode 100644 index 00000000000..a4144ef6a53 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_status_suspend.md @@ -0,0 +1,108 @@ +# POST /nodes/{node}/qemu/{vmid}/status/suspend + +Suspend virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| statestorage | string | no | The storage for the VM state | +| todisk | boolean | no | If set, suspends the VM to disk. Will be resumed on next VM start. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_template.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_template.md new file mode 100644 index 00000000000..87a21339803 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_template.md @@ -0,0 +1,152 @@ +# POST /nodes/{node}/qemu/{vmid}/template + +Create a Template. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | no | If you want to convert only 1 disk to base image. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Allocate" + ] + ], + "description": "You need 'VM.Allocate' permissions on /vms/{vmid}" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_termproxy.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_termproxy.md new file mode 100644 index 00000000000..f06b69b24c2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_termproxy.md @@ -0,0 +1,120 @@ +# POST /nodes/{node}/qemu/{vmid}/termproxy + +Creates a TCP proxy connections. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| serial | string | no | opens a serial terminal (defaults to display) | + +## Returns + +```json +{ + "additionalProperties": 0, + "properties": { + "port": { + "type": "integer" + }, + "ticket": { + "type": "string" + }, + "upid": { + "type": "string" + }, + "user": { + "type": "string" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_vncproxy.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_vncproxy.md new file mode 100644 index 00000000000..c4534e67d58 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_qemu_vmid_vncproxy.md @@ -0,0 +1,139 @@ +# POST /nodes/{node}/qemu/{vmid}/vncproxy + +Creates a TCP VNC proxy connections. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| generate-password | boolean | no | Deprecated, do not use. Password is generated when required. | +| websocket | boolean | no | Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_replication_id_schedule_now.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_replication_id_schedule_now.md new file mode 100644 index 00000000000..0d593de72f3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_replication_id_schedule_now.md @@ -0,0 +1,68 @@ +# POST /nodes/{node}/replication/{id}/schedule_now + +Schedule replication job to start as soon as possible. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | +| node | string | yes | The cluster node name. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_reload.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_reload.md new file mode 100644 index 00000000000..b2bd7012447 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_reload.md @@ -0,0 +1,101 @@ +# POST /nodes/{node}/services/{service}/reload + +Reload service. Falls back to restart if service cannot be reloaded. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_restart.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_restart.md new file mode 100644 index 00000000000..c0c9af98215 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_restart.md @@ -0,0 +1,101 @@ +# POST /nodes/{node}/services/{service}/restart + +Hard restart service. Use reload if you want to reduce interruptions. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_start.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_start.md new file mode 100644 index 00000000000..03733295ac6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_start.md @@ -0,0 +1,101 @@ +# POST /nodes/{node}/services/{service}/start + +Start service. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_stop.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_stop.md new file mode 100644 index 00000000000..c1cd2cc4c6f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_services_service_stop.md @@ -0,0 +1,101 @@ +# POST /nodes/{node}/services/{service}/stop + +Stop service. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| service | string | yes | Service ID | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_spiceshell.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_spiceshell.md new file mode 100644 index 00000000000..9afb6581498 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_spiceshell.md @@ -0,0 +1,137 @@ +# POST /nodes/{node}/spiceshell + +Creates a SPICE shell. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cmd | string | no | Run specific command or default to login (requires 'root@pam') | +| cmd-opts | string | no | Add parameters to a command. Encoded as null terminated strings. | +| proxy | string | no | 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). | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_startall.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_startall.md new file mode 100644 index 00000000000..9b96adb5a59 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_startall.md @@ -0,0 +1,87 @@ +# POST /nodes/{node}/startall + +Start all VMs and containers located on this node (by default only those with onboot=1). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Issue start command even if virtual guest have 'onboot' not set or set to off. | +| max-workers | integer | no | 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. | +| vms | string | no | Only consider guests from this comma separated list of VMIDs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_status.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_status.md new file mode 100644 index 00000000000..5842f3d7ef6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_status.md @@ -0,0 +1,81 @@ +# POST /nodes/{node}/status + +Reboot or shutdown a node. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| command | string | yes | Specify the command. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_stopall.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_stopall.md new file mode 100644 index 00000000000..092671f6506 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_stopall.md @@ -0,0 +1,97 @@ +# POST /nodes/{node}/stopall + +Stop all VMs and Containers. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force-stop | boolean | no | Force a hard-stop after the timeout. | +| max-workers | integer | no | 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. | +| timeout | integer | no | Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced. | +| vms | string | no | Only consider Guests with these IDs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "description": "The 'VM.PowerMgmt' permission is required on '/' or on '/vms/' for each ID passed via the 'vms' parameter.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_content.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_content.md new file mode 100644 index 00000000000..42e4dd7f7fb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_content.md @@ -0,0 +1,116 @@ +# POST /nodes/{node}/storage/{storage}/content + +Allocate disk images. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| filename | string | yes | The name of the file to create. | +| size | string | yes | Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M) | +| vmid | integer | yes | Specify owner VM | +| format | string | no | Format of the image. | + +## Returns + +```json +{ + "description": "Volume identifier", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateSpace" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_content_volume.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_content_volume.md new file mode 100644 index 00000000000..0d20af250fb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_content_volume.md @@ -0,0 +1,82 @@ +# POST /nodes/{node}/storage/{storage}/content/{volume} + +Copy a volume. This is experimental code - do not use. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Source volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| target | string | yes | Target volume identifier | +| target_node | string | no | Target node. Default is local node. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_download_url.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_download_url.md new file mode 100644 index 00000000000..a103670021b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_download_url.md @@ -0,0 +1,187 @@ +# POST /nodes/{node}/storage/{storage}/download-url + +Download templates, ISO images, OVAs and VM images by using an URL. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | yes | Content type. | +| filename | string | yes | The name of the file to create. Caution: This will be normalized! | +| url | string | yes | The URL to download the file from. | +| checksum | string | no | The expected checksum of the file. | +| checksum-algorithm | string | no | The algorithm to calculate the checksum of the file. | +| compression | string | no | Decompress the downloaded file using the specified compression algorithm. | +| verify-certificates | boolean | no | If false, no SSL/TLS certificates will be verified. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_oci_registry_pull.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_oci_registry_pull.md new file mode 100644 index 00000000000..02fb967c6db --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_oci_registry_pull.md @@ -0,0 +1,115 @@ +# POST /nodes/{node}/storage/{storage}/oci-registry-pull + +Pull an OCI image from a registry. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| reference | string | yes | The reference to the OCI image to download. | +| filename | string | no | Custom destination file name of the OCI image. Caution: This will be normalized! | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ], + [ + "perm", + "/nodes/{node}", + [ + "Sys.AccessNetwork" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_upload.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_upload.md new file mode 100644 index 00000000000..afe4ccc7408 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_storage_storage_upload.md @@ -0,0 +1,127 @@ +# POST /nodes/{node}/storage/{storage}/upload + +Upload templates, ISO images, OVAs and VM images. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| content | string | yes | Content type. | +| filename | string | yes | The name of the file to create. Caution: This will be normalized! | +| checksum | string | no | The expected checksum of the file. | +| checksum-algorithm | string | no | The algorithm to calculate the checksum of the file. | +| tmpfilename | string | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage/{storage}", + [ + "Datastore.AllocateTemplate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_subscription.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_subscription.md new file mode 100644 index 00000000000..70279619f5d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_subscription.md @@ -0,0 +1,80 @@ +# POST /nodes/{node}/subscription + +Update subscription info. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Always connect to server, even if local cache is still valid. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_suspendall.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_suspendall.md new file mode 100644 index 00000000000..d4c19cdc33b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_suspendall.md @@ -0,0 +1,79 @@ +# POST /nodes/{node}/suspendall + +Suspend all VMs. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| max-workers | integer | no | Maximal number of parallel migration job. 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. | +| vms | string | no | Only consider Guests with these IDs. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_termproxy.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_termproxy.md new file mode 100644 index 00000000000..f2a9e156e7d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_termproxy.md @@ -0,0 +1,128 @@ +# POST /nodes/{node}/termproxy + +Creates a VNC Shell proxy. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cmd | string | no | Run specific command or default to login (requires 'root@pam') | +| cmd-opts | string | no | Add parameters to a command. Encoded as null terminated strings. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_vncshell.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_vncshell.md new file mode 100644 index 00000000000..446276dad6c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_vncshell.md @@ -0,0 +1,161 @@ +# POST /nodes/{node}/vncshell + +Creates a VNC Shell proxy. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cmd | string | no | Run specific command or default to login (requires 'root@pam') | +| cmd-opts | string | no | Add parameters to a command. Encoded as null terminated strings. | +| height | integer | no | sets the height of the console in pixels. | +| websocket | boolean | no | use websocket instead of standard vnc. | +| width | integer | no | sets the width of the console in pixels. | + +## Returns + +```json +{ + "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" + } + } +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + } + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_vzdump.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_vzdump.md new file mode 100644 index 00000000000..3398faed5cb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_vzdump.md @@ -0,0 +1,344 @@ +# POST /nodes/{node}/vzdump + +Create backup. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | no | Only run if executed on this node. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| all | boolean | no | Backup all known guest systems on this host. | +| bwlimit | integer | no | Limit I/O bandwidth (in KiB/s). | +| compress | string | no | Compress dump file. | +| dumpdir | string | no | Store resulting files to specified directory. | +| exclude | string | no | Exclude specified guest systems (assumes --all) | +| exclude-path | array | no | Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory. | +| fleecing | string | no | Options for backup fleecing (VM only). | +| ionice | integer | no | 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. | +| job-id | string | no | 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. | +| lockwait | integer | no | Maximal time to wait for the global lock (minutes). | +| mailnotification | string | no | Deprecated: use notification targets/matchers instead. Specify when to send a notification mail | +| mailto | string | no | Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications. | +| mode | string | no | Backup mode. | +| notes-template | string | no | 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. | +| notification-mode | string | no | 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. | +| pbs-change-detection-mode | string | no | PBS mode used to detect file changes and switch encoding format for container backups. | +| performance | string | no | Other performance-related settings. | +| pigz | integer | no | Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count. | +| pool | string | no | Backup all known guest systems included in the specified pool. | +| protected | boolean | no | If true, mark backup(s) as protected. | +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| quiet | boolean | no | Be quiet. | +| remove | boolean | no | Prune older backups according to 'prune-backups'. | +| script | string | no | Use specified hook script. | +| stdexcludes | boolean | no | Exclude temporary files and logs. | +| stdout | boolean | no | Write tar to stdout, not to a file. | +| stop | boolean | no | Stop running backup jobs on this host. | +| stopwait | integer | no | Maximal time to wait until a guest system is stopped (minutes). | +| storage | string | no | Store resulting file to this storage. | +| tmpdir | string | no | Store temporary files to specified directory. | +| vmid | string | no | The ID of the guest system you want to backup. | +| zstd | integer | no | 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. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_nodes_node_wakeonlan.md b/docs/pve-api/markdown/endpoints/POST_nodes_node_wakeonlan.md new file mode 100644 index 00000000000..58b97e58830 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_nodes_node_wakeonlan.md @@ -0,0 +1,74 @@ +# POST /nodes/{node}/wakeonlan + +Try to wake a node via 'wake on LAN' network packet. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | target node for wake on LAN packet | + +## Request parameters + +None. + +## Returns + +```json +{ + "description": "MAC address used to assemble the WoL magic packet.", + "format": "mac-addr", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.PowerMgmt" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_pools.md b/docs/pve-api/markdown/endpoints/POST_pools.md new file mode 100644 index 00000000000..0125b1cb098 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_pools.md @@ -0,0 +1,75 @@ +# POST /pools + +Create new pool. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/POST_storage.md b/docs/pve-api/markdown/endpoints/POST_storage.md new file mode 100644 index 00000000000..8ea937bc94b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/POST_storage.md @@ -0,0 +1,681 @@ +# POST /storage + +Create a new storage. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | +| type | string | yes | Storage type. | +| authsupported | string | no | Authsupported. | +| base | string | no | Base volume. This volume is automatically activated. | +| blocksize | string | no | ZFS block size | +| bwlimit | string | no | Set I/O bandwidth limit for various operations (in KiB/s). | +| comstar_hg | string | no | host group for comstar views | +| comstar_tg | string | no | target group for comstar views | +| content | string | no | Allowed content types. NOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs. | +| content-dirs | string | no | Overrides for default content type directories. | +| create-base-path | boolean | no | Create the base directory if it doesn't exist. | +| create-subdirs | boolean | no | Populate the directory with the default structure. | +| data-pool | string | no | Data Pool (for erasure coding only) | +| datastore | string | no | Proxmox Backup Server datastore name. | +| disable | boolean | no | Flag to disable the storage. | +| domain | string | no | CIFS domain. | +| encryption-key | string | no | Encryption key. Use 'autogen' to generate one automatically without passphrase. | +| export | string | no | NFS export path. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| format | string | no | Default image format. | +| fs-name | string | no | The Ceph filesystem name. | +| fuse | boolean | no | Mount CephFS through FUSE. | +| is_mountpoint | string | no | 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. | +| iscsiprovider | string | no | iscsi provider | +| keyring | string | no | Client keyring contents (for external clusters). | +| krbd | boolean | no | Always access rbd through krbd kernel module. | +| lio_tpg | string | no | target portal group for Linux LIO targets | +| master-pubkey | string | no | Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup. | +| max-protected-backups | integer | no | Maximal number of protected backups per guest. Use '-1' for unlimited. | +| mkdir | boolean | no | 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. | +| monhost | string | no | IP addresses of monitors (for external clusters). | +| mountpoint | string | no | mount point | +| namespace | string | no | Namespace. | +| nocow | boolean | no | 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. | +| nodes | string | no | List of nodes for which the storage configuration applies. | +| nowritecache | boolean | no | disable write caching on the target | +| options | string | no | NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs') | +| password | string | no | Password for accessing the share/datastore. | +| path | string | no | File system path. | +| pool | string | no | Pool. | +| port | integer | no | 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. | +| portal | string | no | iSCSI portal (IP or DNS name with optional port). | +| preallocation | string | no | Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. | +| prune-backups | string | no | 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. | +| saferemove | boolean | no | Zero-out data when removing LVs. | +| saferemove_throughput | string | no | Wipe throughput (cstream -t parameter value). | +| saferemove-stepsize | integer | no | Wipe step size in MiB. It will be capped to the maximum supported by the storage. | +| server | string | no | Server IP or DNS name. | +| share | string | no | CIFS share. | +| shared | boolean | no | 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! | +| skip-cert-verification | boolean | no | Disable TLS certificate verification, only enable on fully trusted networks! | +| smbversion | string | no | SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. | +| snapshot-as-volume-chain | boolean | no | Enable support for creating storage-vendor agnostic snapshot through volume backing-chains. | +| sparse | boolean | no | use sparse volumes | +| subdir | string | no | Subdir to mount. | +| tagged_only | boolean | no | Only list logical volumes tagged with 'pve-vm-ID'. | +| target | string | no | iSCSI target. | +| thinpool | string | no | LVM thin pool LV name. | +| username | string | no | RBD Id. | +| vgname | string | no | Volume group name. | +| zfs-base-path | string | no | Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_acl.md b/docs/pve-api/markdown/endpoints/PUT_access_acl.md new file mode 100644 index 00000000000..70935d0b378 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_acl.md @@ -0,0 +1,109 @@ +# PUT /access/acl + +Update Access Control List (add or remove permissions). + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| path | string | yes | Access control path | +| roles | string | yes | List of roles. | +| delete | boolean | no | Remove permissions (instead of adding it). | +| groups | string | no | List of groups. | +| propagate | boolean | no | Allow to propagate (inherit) permissions. | +| tokens | string | no | List of API tokens. | +| users | string | no | List of users. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm-modify", + "{path}" + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_domains_realm.md b/docs/pve-api/markdown/endpoints/PUT_access_domains_realm.md new file mode 100644 index 00000000000..feb5f16aa30 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_domains_realm.md @@ -0,0 +1,416 @@ +# PUT /access/domains/{realm} + +Update authentication server settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| realm | string | yes | Authentication domain ID | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acr-values | string | no | Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request. | +| audiences | string | no | A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'. | +| autocreate | boolean | no | Automatically create users if they do not exist. | +| base_dn | string | no | LDAP base domain name | +| bind_dn | string | no | LDAP bind domain name | +| capath | string | no | Path to the CA certificate store | +| case-sensitive | boolean | no | username is case-sensitive | +| cert | string | no | Path to the client certificate | +| certkey | string | no | Path to the client certificate key | +| check-connection | boolean | no | Check bind connection to the server. | +| client-id | string | no | OpenID Client ID | +| client-key | string | no | OpenID Client Key | +| comment | string | no | Description. | +| default | boolean | no | Use this as default realm | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| domain | string | no | AD domain name | +| filter | string | no | LDAP filter for user sync. | +| group_classes | string | no | The objectclasses for groups. | +| group_dn | string | no | LDAP base domain name for group sync. If not set, the base_dn will be used. | +| group_filter | string | no | LDAP filter for group sync. | +| group_name_attr | string | no | LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name. | +| groups-autocreate | boolean | no | Automatically create groups if they do not exist. | +| groups-claim | string | no | OpenID claim used to retrieve groups with. | +| groups-overwrite | boolean | no | All groups will be overwritten for the user on login. | +| issuer-url | string | no | OpenID Issuer Url | +| mode | string | no | LDAP protocol mode. | +| password | string | no | LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'. | +| port | integer | no | Server port. | +| prompt | string | no | Specifies whether the Authorization Server prompts the End-User for reauthentication and consent. | +| query-userinfo | boolean | no | Enables querying the userinfo endpoint for claims values. | +| scopes | string | no | Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'. | +| secure | boolean | no | Use secure LDAPS protocol. DEPRECATED: use 'mode' instead. | +| server1 | string | no | Server IP address (or DNS name) | +| server2 | string | no | Fallback Server IP address (or DNS name) | +| sslversion | string | no | LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! | +| sync_attributes | string | no | 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. | +| sync-defaults-options | string | no | The default options for behavior of synchronizations. | +| tfa | string | no | Use Two-factor authentication. | +| user_attr | string | no | LDAP user attribute name | +| user_classes | string | no | The objectclasses for users. | +| verify | boolean | no | Verify the server's SSL certificate | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/realm", + [ + "Realm.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_groups_groupid.md b/docs/pve-api/markdown/endpoints/PUT_access_groups_groupid.md new file mode 100644 index 00000000000..5cd3436b547 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_groups_groupid.md @@ -0,0 +1,76 @@ +# PUT /access/groups/{groupid} + +Update group data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| groupid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access/groups", + [ + "Group.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_password.md b/docs/pve-api/markdown/endpoints/PUT_access_password.md new file mode 100644 index 00000000000..ea47db634e0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_password.md @@ -0,0 +1,116 @@ +# PUT /access/password + +Change user password. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| password | string | yes | The new password. | +| userid | string | yes | Full User ID, in the `name@realm` format. | +| confirmation-password | string | no | The current password of the user performing the change. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_roles_roleid.md b/docs/pve-api/markdown/endpoints/PUT_access_roles_roleid.md new file mode 100644 index 00000000000..3f74fdd29cd --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_roles_roleid.md @@ -0,0 +1,84 @@ +# PUT /access/roles/{roleid} + +Update an existing role. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| roleid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| append | boolean | no | | +| privs | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/access", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_tfa_userid_id.md b/docs/pve-api/markdown/endpoints/PUT_access_tfa_userid_id.md new file mode 100644 index 00000000000..108f8601fd0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_tfa_userid_id.md @@ -0,0 +1,114 @@ +# PUT /access/tfa/{userid}/{id} + +Add a TFA entry for a user. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | A TFA entry id. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| description | string | no | A description to distinguish multiple entries from one another | +| enable | boolean | no | Whether the entry should be enabled for login. | +| password | string | no | The current password of the user performing the change. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_users_userid.md b/docs/pve-api/markdown/endpoints/PUT_access_users_userid.md new file mode 100644 index 00000000000..23726983b5e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_users_userid.md @@ -0,0 +1,140 @@ +# PUT /access/users/{userid} + +Update user configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| append | boolean | no | | +| comment | string | no | | +| email | string | no | | +| enable | boolean | no | Enable the account (default). You can set this to '0' to disable the account | +| expire | integer | no | Account expiration date (seconds since epoch). '0' means no expiration date. | +| firstname | string | no | | +| groups | string | no | | +| keys | string | no | Keys for two factor auth (yubico). | +| lastname | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "userid-group", + [ + "User.Modify" + ], + "groups_param", + "update" + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_users_userid_token_tokenid.md b/docs/pve-api/markdown/endpoints/PUT_access_users_userid_token_tokenid.md new file mode 100644 index 00000000000..1cd3db17c6b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_users_userid_token_tokenid.md @@ -0,0 +1,189 @@ +# PUT /access/users/{userid}/token/{tokenid} + +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! + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| tokenid | string | yes | User-specific token identifier. | +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| delete | string | no | A list of settings you want to delete. | +| expire | integer | no | API token expiration date (seconds since epoch). '0' means no expiration date. | +| privsep | boolean | no | Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user. | +| regenerate | boolean | no | Regenerate the token's secret value. All users of the previous secret will lose access after this operation. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "or", + [ + "userid-param", + "self" + ], + [ + "userid-group", + [ + "User.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_access_users_userid_unlock_tfa.md b/docs/pve-api/markdown/endpoints/PUT_access_users_userid_unlock_tfa.md new file mode 100644 index 00000000000..565fe3b7f8e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_access_users_userid_unlock_tfa.md @@ -0,0 +1,69 @@ +# PUT /access/users/{userid}/unlock-tfa + +Unlock a user's TFA authentication. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| userid | string | yes | Full User ID, in the `name@realm` format. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "boolean" +} +``` + +## Permissions + +```json +{ + "check": [ + "userid-group", + [ + "User.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_acme_account_name.md b/docs/pve-api/markdown/endpoints/PUT_cluster_acme_account_name.md new file mode 100644 index 00000000000..efab8ad207b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_acme_account_name.md @@ -0,0 +1,63 @@ +# PUT /cluster/acme/account/{name} + +Update existing ACME account information with CA. Note: not specifying any new account information triggers a refresh. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | no | ACME account config file name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| contact | string | no | Contact email addresses. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_acme_plugins_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_acme_plugins_id.md new file mode 100644 index 00000000000..f2a139a2e6e --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_acme_plugins_id.md @@ -0,0 +1,289 @@ +# PUT /cluster/acme/plugins/{id} + +Update ACME plugin configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | ACME Plugin ID name | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| api | string | no | API plugin name | +| data | string | no | DNS plugin data. (base64 encoded) | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable the config. | +| nodes | string | no | List of cluster node names. | +| validation-delay | integer | no | Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_backup_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_backup_id.md new file mode 100644 index 00000000000..e5e138d2f8b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_backup_id.md @@ -0,0 +1,405 @@ +# PUT /cluster/backup/{id} + +Update vzdump backup job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The job ID. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| all | boolean | no | Backup all known guest systems on this host. | +| bwlimit | integer | no | Limit I/O bandwidth (in KiB/s). | +| comment | string | no | Description for the Job. | +| compress | string | no | Compress dump file. | +| delete | string | no | A list of settings you want to delete. | +| dow | string | no | Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| dumpdir | string | no | Store resulting files to specified directory. | +| enabled | boolean | no | Enable or disable the job. | +| exclude | string | no | Exclude specified guest systems (assumes --all) | +| exclude-path | array | no | Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory. | +| fleecing | string | no | Options for backup fleecing (VM only). | +| ionice | integer | no | 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. | +| lockwait | integer | no | Maximal time to wait for the global lock (minutes). | +| mailnotification | string | no | Deprecated: use notification targets/matchers instead. Specify when to send a notification mail | +| mailto | string | no | Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications. | +| mode | string | no | Backup mode. | +| node | string | no | Only run if executed on this node. | +| notes-template | string | no | 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. | +| notification-mode | string | no | 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. | +| pbs-change-detection-mode | string | no | PBS mode used to detect file changes and switch encoding format for container backups. | +| performance | string | no | Other performance-related settings. | +| pigz | integer | no | Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count. | +| pool | string | no | Backup all known guest systems included in the specified pool. | +| protected | boolean | no | If true, mark backup(s) as protected. | +| prune-backups | string | no | Use these retention options instead of those from the storage configuration. | +| quiet | boolean | no | Be quiet. | +| remove | boolean | no | Prune older backups according to 'prune-backups'. | +| repeat-missed | boolean | no | If true, the job will be run as soon as possible if it was missed while the scheduler was not running. | +| schedule | string | no | Backup schedule. The format is a subset of `systemd` calendar events. | +| script | string | no | Use specified hook script. | +| starttime | string | no | Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used. | +| stdexcludes | boolean | no | Exclude temporary files and logs. | +| stop | boolean | no | Stop running backup jobs on this host. | +| stopwait | integer | no | Maximal time to wait until a guest system is stopped (minutes). | +| storage | string | no | Store resulting file to this storage. | +| tmpdir | string | no | Store temporary files to specified directory. | +| vmid | string | no | The ID of the guest system you want to backup. | +| zstd | integer | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ], + "description": "The 'tmpdir', 'dumpdir' and 'script' parameters are additionally restricted to the 'root@pam' user." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_ceph_flags.md b/docs/pve-api/markdown/endpoints/PUT_cluster_ceph_flags.md new file mode 100644 index 00000000000..fe1a9118dd1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_ceph_flags.md @@ -0,0 +1,140 @@ +# PUT /cluster/ceph/flags + +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. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| nobackfill | boolean | no | Backfilling of PGs is suspended. | +| nodeep-scrub | boolean | no | Deep Scrubbing is disabled. | +| nodown | boolean | no | OSD failure reports are being ignored, such that the monitors will not mark OSDs down. | +| noin | boolean | no | OSDs that were previously marked out will not be marked back in when they start. | +| noout | boolean | no | OSDs will not automatically be marked out after the configured interval. | +| norebalance | boolean | no | Rebalancing of PGs is suspended. | +| norecover | boolean | no | Recovery of PGs is suspended. | +| noscrub | boolean | no | Scrubbing is disabled. | +| notieragent | boolean | no | Cache tiering activity is suspended. | +| noup | boolean | no | OSDs are not allowed to start. | +| pause | boolean | no | Pauses read and writes. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_ceph_flags_flag.md b/docs/pve-api/markdown/endpoints/PUT_cluster_ceph_flags_flag.md new file mode 100644 index 00000000000..7f5ce223087 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_ceph_flags_flag.md @@ -0,0 +1,88 @@ +# PUT /cluster/ceph/flags/{flag} + +Set or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| flag | string | yes | The ceph flag to update | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| value | boolean | yes | The new value of the flag | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_aliases_name.md new file mode 100644 index 00000000000..26597862138 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_aliases_name.md @@ -0,0 +1,102 @@ +# PUT /cluster/firewall/aliases/{name} + +Update IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing alias. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_groups_group_pos.md b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_groups_group_pos.md new file mode 100644 index 00000000000..aca7c9f34e1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_groups_group_pos.md @@ -0,0 +1,226 @@ +# PUT /cluster/firewall/groups/{group}/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | Security Group name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..10b9169b95b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_ipset_name_cidr.md @@ -0,0 +1,99 @@ +# PUT /cluster/firewall/ipset/{name}/{cidr} + +Update IP or Network settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_options.md b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_options.md new file mode 100644 index 00000000000..70ceb62c4bb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_options.md @@ -0,0 +1,158 @@ +# PUT /cluster/firewall/options + +Set Firewall options. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| ebtables | boolean | no | Enable ebtables rules cluster wide. | +| enable | integer | no | Enable or disable the firewall cluster wide. | +| log_ratelimit | string | no | Log ratelimiting settings | +| policy_forward | string | no | Forward policy. | +| policy_in | string | no | Input policy. | +| policy_out | string | no | Output policy. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_rules_pos.md new file mode 100644 index 00000000000..a93521ef0cb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_firewall_rules_pos.md @@ -0,0 +1,218 @@ +# PUT /cluster/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_ha_groups_group.md b/docs/pve-api/markdown/endpoints/PUT_cluster_ha_groups_group.md new file mode 100644 index 00000000000..7d09c976040 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_ha_groups_group.md @@ -0,0 +1,123 @@ +# PUT /cluster/ha/groups/{group} + +Update ha group configuration. (deprecated in favor of HA rules) + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| group | string | yes | The HA group identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nodes | string | no | List of cluster node names with optional priority. | +| nofailback | boolean | no | 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. | +| restricted | boolean | no | Resources bound to restricted groups may only run on nodes defined by the group. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_ha_resources_sid.md b/docs/pve-api/markdown/endpoints/PUT_cluster_ha_resources_sid.md new file mode 100644 index 00000000000..3f499a8eb4f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_ha_resources_sid.md @@ -0,0 +1,154 @@ +# PUT /cluster/ha/resources/{sid} + +Update resource configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| sid | string | yes | 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). | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| auto-rebalance | boolean | no | HA resource may be migrated during automatic rebalancing | +| comment | string | no | Description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| failback | boolean | no | 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. | +| group | string | no | The HA group identifier. | +| max_relocate | integer | no | Maximal number of resource relocate tries when a resource fails to start. | +| max_restart | integer | no | 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. | +| state | string | no | Requested resource state. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_ha_rules_rule.md b/docs/pve-api/markdown/endpoints/PUT_cluster_ha_rules_rule.md new file mode 100644 index 00000000000..d09e37f6e3d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_ha_rules_rule.md @@ -0,0 +1,162 @@ +# PUT /cluster/ha/rules/{rule} + +Update HA rule. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| rule | string | yes | HA rule identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | HA rule type. | +| affinity | string | no | 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'). | +| comment | string | no | HA rule description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Whether the HA rule is disabled. | +| nodes | string | no | List of cluster node names with optional priority. | +| resources | string | no | 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). | +| strict | boolean | no | Describes whether the node affinity rule is strict or non-strict. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_jobs_realm_sync_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_jobs_realm_sync_id.md new file mode 100644 index 00000000000..be2120bcd78 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_jobs_realm_sync_id.md @@ -0,0 +1,156 @@ +# PUT /cluster/jobs/realm-sync/{id} + +Update realm-sync job definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the job. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| schedule | string | yes | Backup schedule. The format is a subset of `systemd` calendar events. | +| comment | string | no | Description for the Job. | +| delete | string | no | A list of settings you want to delete. | +| enable-new | boolean | no | Enable newly synced users immediately. | +| enabled | boolean | no | Determines if the job is enabled. | +| remove-vanished | string | no | 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). | +| scope | string | no | Select what to sync. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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/'." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_dir_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_dir_id.md new file mode 100644 index 00000000000..5856c04fe61 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_dir_id.md @@ -0,0 +1,119 @@ +# PUT /cluster/mapping/dir/{id} + +Update a directory mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the directory mapping | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description of the directory mapping | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| map | array | no | A list of maps for the cluster nodes. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/dir/{id}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_pci_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_pci_id.md new file mode 100644 index 00000000000..4f8d2f7fbe8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_pci_id.md @@ -0,0 +1,157 @@ +# PUT /cluster/mapping/pci/{id} + +Update a hardware mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical PCI mapping. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description of the logical PCI device. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| live-migration-capable | boolean | no | Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work. | +| map | array | no | A list of maps for the cluster nodes. | +| mdev | boolean | no | Marks the device(s) as being capable of providing mediated devices. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/pci/{id}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_usb_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_usb_id.md new file mode 100644 index 00000000000..fc88c5aa787 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_mapping_usb_id.md @@ -0,0 +1,130 @@ +# PUT /cluster/mapping/usb/{id} + +Update a hardware mapping. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the logical USB mapping. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| map | array | yes | A list of maps for the cluster nodes. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description of the logical USB device. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/usb/{id}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_metrics_server_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_metrics_server_id.md new file mode 100644 index 00000000000..166827ca905 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_metrics_server_id.md @@ -0,0 +1,277 @@ +# PUT /cluster/metrics/server/{id} + +Update metric server configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The ID of the entry. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| port | integer | yes | server network port | +| server | string | yes | server dns name or IP address | +| api-path-prefix | string | no | An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy. | +| bucket | string | no | The InfluxDB bucket/db. Only necessary when using the http v2 api. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable the plugin. | +| influxdbproto | string | no | | +| max-body-size | integer | no | InfluxDB max-body-size in bytes. Requests are batched up to this size. | +| mtu | integer | no | MTU for metrics transmission over UDP | +| organization | string | no | The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api. | +| otel-compression | string | no | Compression algorithm for requests | +| otel-headers | string | no | Custom HTTP headers (JSON format, base64 encoded) | +| otel-max-body-size | integer | no | Maximum request body size in bytes | +| otel-path | string | no | OTLP endpoint path | +| otel-protocol | string | no | HTTP protocol | +| otel-resource-attributes | string | no | Additional resource attributes as JSON, base64 encoded | +| otel-timeout | integer | no | HTTP request timeout in seconds | +| otel-verify-ssl | boolean | no | Verify SSL certificates | +| path | string | no | root graphite path (ex: proxmox.mycluster.mykey) | +| proto | string | no | Protocol to send graphite data. TCP or UDP (default) | +| timeout | integer | no | graphite TCP socket timeout (default=1) | +| token | string | no | The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead. | +| verify-certificate | boolean | no | Set to 0 to disable certificate verification for https endpoints. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_gotify_name.md b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_gotify_name.md new file mode 100644 index 00000000000..3a62c70dcb5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_gotify_name.md @@ -0,0 +1,161 @@ +# PUT /cluster/notifications/endpoints/gotify/{name} + +Update existing gotify endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| server | string | no | Server URL | +| token | string | no | Secret token | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_sendmail_name.md b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_sendmail_name.md new file mode 100644 index 00000000000..75edd108a09 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_sendmail_name.md @@ -0,0 +1,183 @@ +# PUT /cluster/notifications/endpoints/sendmail/{name} + +Update existing sendmail endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| author | string | no | Author of the mail | +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| from-address | string | no | `From` address for the mail | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_smtp_name.md b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_smtp_name.md new file mode 100644 index 00000000000..975155f3898 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_smtp_name.md @@ -0,0 +1,223 @@ +# PUT /cluster/notifications/endpoints/smtp/{name} + +Update existing smtp endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| author | string | no | Author of the mail. Defaults to 'Proxmox VE'. | +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| from-address | string | no | `From` address for the mail | +| mailto | array | no | List of email recipients | +| mailto-user | array | no | List of users | +| mode | string | no | Determine which encryption method shall be used for the connection. | +| password | string | no | Password for SMTP authentication | +| port | integer | no | 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. | +| server | string | no | The address of the SMTP server. | +| username | string | no | Username for SMTP authentication | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_webhook_name.md b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_webhook_name.md new file mode 100644 index 00000000000..f6888f11c44 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_endpoints_webhook_name.md @@ -0,0 +1,192 @@ +# PUT /cluster/notifications/endpoints/webhook/{name} + +Update existing webhook endpoint + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the endpoint. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| body | string | no | HTTP body, base64 encoded | +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this target | +| header | array | no | HTTP headers to set. These have to be formatted as a property string in the format name=,value= | +| method | string | no | HTTP method | +| secret | array | no | Secrets to set. These have to be formatted as a property string in the format name=,value= | +| url | string | no | Server URL | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ], + [ + "or", + [ + "perm", + "/", + [ + "Sys.Audit", + "Sys.Modify" + ] + ], + [ + "perm", + "/", + [ + "Sys.AccessNetwork" + ] + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_matchers_name.md b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_matchers_name.md new file mode 100644 index 00000000000..fcf865a6687 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_notifications_matchers_name.md @@ -0,0 +1,164 @@ +# PUT /cluster/notifications/matchers/{name} + +Update existing matcher + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Name of the matcher. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Comment | +| delete | array | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Disable this matcher | +| invert-match | boolean | no | Invert match of the whole matcher | +| match-calendar | array | no | Match notification timestamp | +| match-field | array | no | Metadata fields to match (regex or exact match). Must be in the form (regex\|exact):= | +| match-severity | array | no | Notification severities to match | +| mode | string | no | Choose between 'all' and 'any' for when multiple properties are specified | +| target | array | no | Targets to notify on match | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/notifications", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_options.md b/docs/pve-api/markdown/endpoints/PUT_cluster_options.md new file mode 100644 index 00000000000..2b3b444c229 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_options.md @@ -0,0 +1,651 @@ +# PUT /cluster/options + +Set datacenter options. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| bwlimit | string | no | Set I/O bandwidth limit for various operations (in KiB/s). | +| consent-text | string | no | Consent text that is displayed before logging in. | +| console | string | no | 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. | +| crs | string | no | Cluster resource scheduling settings. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file. | +| email_from | string | no | Specify email address to send notification from (default is root@$hostname) | +| fencing | string | no | 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. WARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP | +| ha | string | no | Cluster wide HA settings. | +| http_proxy | string | no | Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/') | +| keyboard | string | no | Default keybord layout for vnc server. | +| language | string | no | Default GUI language. | +| location | string | no | The location of the cluster. | +| mac_prefix | string | no | 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). | +| max_workers | integer | no | Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager. | +| migration | string | no | For cluster wide migration settings. | +| migration_unsecure | boolean | no | 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! | +| next-id | string | no | Control the range for the free VMID auto-selection pool. | +| notify | string | no | Cluster-wide notification settings. | +| registered-tags | string | no | 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`. | +| replication | string | no | For cluster wide replication settings. | +| tag-style | string | no | Tag style options. | +| u2f | string | no | u2f | +| user-tag-access | string | no | Privilege options for user-settable tags | +| webauthn | string | no | webauthn configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_qemu_custom_cpu_models_cputype.md b/docs/pve-api/markdown/endpoints/PUT_cluster_qemu_custom_cpu_models_cputype.md new file mode 100644 index 00000000000..ec0dd70ffd6 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_qemu_custom_cpu_models_cputype.md @@ -0,0 +1,259 @@ +# PUT /cluster/qemu/custom-cpu-models/{cputype} + +Update a custom CPU model definition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cputype | string | yes | Name for the custom CPU model. The 'custom-' prefix is optional. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of properties to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| flags | string | no | 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 | +| guest-phys-bits | integer | no | Number of physical address bits available to the guest. | +| hidden | boolean | no | Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture. | +| hv-vendor-id | string | no | The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID. | +| level | integer | no | 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. | +| phys-bits | string | no | 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. | +| reported-model | string | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/mapping/cpu/{cputype}", + [ + "Mapping.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_replication_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_replication_id.md new file mode 100644 index 00000000000..b5cdea17502 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_replication_id.md @@ -0,0 +1,130 @@ +# PUT /cluster/replication/{id} + +Update replication job configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | Description. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable/deactivate the entry. | +| rate | number | no | Rate limit in mbps (megabytes per second) as floating point number. | +| remove_job | string | no | 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. | +| schedule | string | no | Storage replication schedule. The format is a subset of `systemd` calendar events. | +| source | string | no | For internal use, to detect if the guest was stolen. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Requires the VM.Replicate permission on /vms/.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn.md new file mode 100644 index 00000000000..9f6d57adfa8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn.md @@ -0,0 +1,78 @@ +# PUT /cluster/sdn + +Apply sdn controller changes && reload. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| lock-token | string | no | the token for unlocking the global SDN configuration | +| release-lock | boolean | no | When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_controllers_controller.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_controllers_controller.md new file mode 100644 index 00000000000..4d53504203b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_controllers_controller.md @@ -0,0 +1,228 @@ +# PUT /cluster/sdn/controllers/{controller} + +Update sdn controller object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| controller | string | yes | The SDN controller object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| asn | integer | no | autonomous system number | +| bgp-mode | string | no | Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. | +| bgp-multipath-as-path-relax | boolean | no | Consider different AS paths of equal length for multipath computation. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| ebgp | boolean | no | Enable eBGP (remote-as external). | +| ebgp-multihop | integer | no | Set maximum amount of hops for eBGP peers. | +| fabric | string | no | SDN fabric to use as underlay for this EVPN controller. | +| isis-domain | string | no | Name of the IS-IS domain. | +| isis-ifaces | string | no | Comma-separated list of interfaces where IS-IS should be active. | +| isis-net | string | no | Network Entity title for this node in the IS-IS network. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| loopback | string | no | Name of the loopback/dummy interface that provides the Router-IP. | +| node | string | no | The cluster node name. | +| nodes | string | no | List of cluster node names. | +| peer-group-name | string | no | Name of the peer group for this EVPN controller | +| peers | string | no | peers address list. | +| route-map-in | string | no | Route Map that should be applied for incoming routes | +| route-map-out | string | no | Route Map that should be applied for outgoing routes | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/controllers", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_dns_dns.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_dns_dns.md new file mode 100644 index 00000000000..85f0c8f3143 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_dns_dns.md @@ -0,0 +1,127 @@ +# PUT /cluster/sdn/dns/{dns} + +Update sdn dns object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| dns | string | yes | The SDN dns object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| key | string | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| reversemaskv6 | integer | no | | +| ttl | integer | no | | +| url | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/dns", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_fabrics_fabric_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_fabrics_fabric_id.md new file mode 100644 index 00000000000..e70e1741b51 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_fabrics_fabric_id.md @@ -0,0 +1,308 @@ +# PUT /cluster/sdn/fabrics/fabric/{id} + +Update a fabric + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | Identifier for SDN fabrics | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | array | yes | | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| redistribute | array | yes | | +| area | string | no | OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust. | +| csnp_interval | number | no | The csnp_interval property for Openfabric | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| hello_interval | number | no | The hello_interval property for Openfabric | +| ip_prefix | string | no | The IP prefix for Node IPs | +| ip6_prefix | string | no | The IP prefix for Node IPs | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| persistent_keepalive | number | no | 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 | +| route_filter | string | no | A prefix list that should be used for filtering routes that are to be installed into the kernel routing table | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/fabrics/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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": [ + "hello_interval", + "csnp_interval", + "route_filter" + ], + "type": "string" + }, + "optional": 1, + "type": "array" + }, + { + "instance-types": [ + "bgp" + ], + "items": { + "enum": [ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_fabrics_node_fabric_id_node_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_fabrics_node_fabric_id_node_id.md new file mode 100644 index 00000000000..d07f81291f1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_fabrics_node_fabric_id_node_id.md @@ -0,0 +1,394 @@ +# PUT /cluster/sdn/fabrics/node/{fabric_id}/{node_id} + +Update a node + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| fabric_id | string | yes | Identifier for SDN fabrics | +| node_id | string | yes | Identifier for nodes in an SDN fabric | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | array | yes | | +| interfaces | array | yes | | +| protocol | string | yes | Type of configuration entry in an SDN Fabric section config | +| allowed_ips | array | no | A list of IPs that are routable via this node in the WireGuard fabric. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| endpoint | string | no | The endpoint used for connecting to this node. | +| ip | string | no | IPv4 address for this node | +| ip6 | string | no | IPv6 address for this node | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| peers | array | no | | +| public_key | string | no | The public key for the external node. | +| role | string | no | The role of this node in the WireGuard fabric. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "and", + [ + "perm", + "/sdn/fabrics/{fabric_id}", + [ + "SDN.Allocate" + ] + ], + [ + "perm", + "/nodes/{node_id}", + [ + "Sys.Modify" + ] + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } + }, + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_ipams_ipam.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_ipams_ipam.md new file mode 100644 index 00000000000..e9e64a7ff95 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_ipams_ipam.md @@ -0,0 +1,121 @@ +# PUT /cluster/sdn/ipams/{ipam} + +Update sdn ipam object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ipam | string | yes | The SDN ipam object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| section | integer | no | | +| token | string | no | | +| url | string | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/ipams", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_prefix_lists_id.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_prefix_lists_id.md new file mode 100644 index 00000000000..597650b0ad4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_prefix_lists_id.md @@ -0,0 +1,139 @@ +# PUT /cluster/sdn/prefix-lists/{id} + +Update Prefix List + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| id | string | yes | The SDN prefix list identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | array | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| entries | array | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_prefix_lists_id_entries_url_seq.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_prefix_lists_id_entries_url_seq.md new file mode 100644 index 00000000000..de407e95548 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_prefix_lists_id_entries_url_seq.md @@ -0,0 +1,131 @@ +# PUT /cluster/sdn/prefix-lists/{id}/entries/{url_seq} + +Update Prefix List Entry + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | | +| delete | array | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| ge | integer | no | | +| le | integer | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| prefix | string | no | | +| seq | integer | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/prefix-lists/{id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_route_maps_entries_route_map_id_entry_order.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_route_maps_entries_route_map_id_entry_order.md new file mode 100644 index 00000000000..cde56c0b071 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_route_maps_entries_route_map_id_entry_order.md @@ -0,0 +1,216 @@ +# PUT /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order} + +Update Route Map Entry + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| order | integer | yes | The index of this route map entry | +| route-map-id | string | yes | The SDN route map identifier | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Matching policy of a route map entry. | +| call | string | no | The SDN route map identifier | +| delete | array | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| exit-action | string | no | | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| match | array | no | | +| set | array | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/route-maps/{route-map-id}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet.md new file mode 100644 index 00000000000..ba392d5ea13 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet.md @@ -0,0 +1,125 @@ +# PUT /cluster/sdn/vnets/{vnet} + +Update sdn vnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| alias | string | no | Alias name of the VNet. | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| isolate-ports | boolean | no | If true, sets the isolated property for all interfaces on the bridge of this VNet. | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| tag | integer | no | VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones). | +| vlanaware | boolean | no | Allow VLANs to pass through this vnet. | +| zone | string | no | Name of the zone this VNet belongs to. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_firewall_options.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_firewall_options.md new file mode 100644 index 00000000000..e793af2758f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_firewall_options.md @@ -0,0 +1,113 @@ +# PUT /cluster/sdn/vnets/{vnet}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable/disable firewall rules. | +| log_level_forward | string | no | Log level for forwarded traffic. | +| policy_forward | string | no | Forward policy. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_firewall_rules_pos.md new file mode 100644 index 00000000000..2923cf4c68c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_firewall_rules_pos.md @@ -0,0 +1,216 @@ +# PUT /cluster/sdn/vnets/{vnet}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Needs SDN.Allocate permissions on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_ips.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_ips.md new file mode 100644 index 00000000000..35d6b0b77c5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_ips.md @@ -0,0 +1,107 @@ +# PUT /cluster/sdn/vnets/{vnet}/ips + +Update IP Mapping in a VNet + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| vnet | string | yes | The SDN vnet object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| ip | string | yes | The IP address to associate with the given MAC address | +| zone | string | yes | The SDN zone object identifier. | +| mac | string | no | Unicast MAC address. | +| vmid | integer | no | The (unique) ID of the VM. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}/{vnet}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_subnets_subnet.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_subnets_subnet.md new file mode 100644 index 00000000000..83018489204 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_vnets_vnet_subnets_subnet.md @@ -0,0 +1,135 @@ +# PUT /cluster/sdn/vnets/{vnet}/subnets/{subnet} + +Update sdn subnet object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| subnet | string | yes | The SDN subnet object identifier. | +| vnet | string | no | associated vnet | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| dhcp-dns-server | string | no | IP address for the DNS server | +| dhcp-range | array | no | A list of DHCP ranges for this subnet | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dnszoneprefix | string | no | dns domain zone prefix ex: 'adm' -> .adm.mydomain.com | +| gateway | string | no | Subnet Gateway: Will be assign on vnet for layer3 zones | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| snat | boolean | no | enable masquerade for this subnet if pve-firewall | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "Require 'SDN.Allocate' permission on '/sdn/zones//'", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_zones_zone.md b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_zones_zone.md new file mode 100644 index 00000000000..49fecd30376 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_cluster_sdn_zones_zone.md @@ -0,0 +1,299 @@ +# PUT /cluster/sdn/zones/{zone} + +Update sdn zone object configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| zone | string | yes | The SDN zone object identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| advertise-subnets | boolean | no | Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes). | +| bridge | string | no | The bridge for which VLANs should be managed. | +| bridge-disable-mac-learning | boolean | no | Disable auto mac learning. | +| controller | string | no | Controller for this zone. | +| delete | string | no | A list of settings you want to delete. | +| dhcp | string | no | Type of the DHCP backend for this zone | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable-arp-nd-suppression | boolean | no | Suppress IPv4 ARP && IPv6 Neighbour Discovery messages. | +| dns | string | no | dns api server | +| dnszone | string | no | dns domain zone ex: mydomain.com | +| dp-id | integer | no | Faucet dataplane id | +| exitnodes | string | no | List of cluster node names. | +| exitnodes-local-routing | boolean | no | Allow exitnodes to connect to EVPN guests. | +| exitnodes-primary | string | no | Force traffic through this exitnode first. | +| fabric | string | no | SDN fabric to use as underlay for this VXLAN zone. | +| ipam | string | no | use a specific ipam | +| lock-token | string | no | the token for unlocking the global SDN configuration | +| mac | string | no | Anycast logical router mac address. | +| mtu | integer | no | MTU of the zone, will be used for the created VNet bridges. | +| nodes | string | no | List of cluster node names. | +| peers | string | no | Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes. | +| reversedns | string | no | reverse dns api server | +| rt-import | string | no | List of Route Targets that should be imported into the VRF of the zone. | +| secondary-controllers | array | no | Additional controllers. | +| tag | integer | no | Service-VLAN Tag (outer VLAN) | +| vlan-protocol | string | no | Which VLAN protocol should be used for the creation of the QinQ zone. | +| vrf-vxlan | integer | no | VNI for the zone VRF. | +| vxlan-port | integer | no | UDP port that should be used for the VXLAN tunnel (default 4789). | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/sdn/zones/{zone}", + [ + "SDN.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_apt_repositories.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_apt_repositories.md new file mode 100644 index 00000000000..d0984ea30d1 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_apt_repositories.md @@ -0,0 +1,86 @@ +# PUT /nodes/{node}/apt/repositories + +Add a standard repository to the configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| handle | string | yes | Handle that identifies a repository. | +| digest | string | no | Digest to detect modifications. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_ceph_pool_name.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_ceph_pool_name.md new file mode 100644 index 00000000000..f4c9f77baab --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_ceph_pool_name.md @@ -0,0 +1,166 @@ +# PUT /nodes/{node}/ceph/pool/{name} + +Change POOL settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | The name of the pool. It must be unique. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| application | string | no | The application of the pool. | +| crush_rule | string | no | The rule to use for mapping object placement in the cluster. | +| min_size | integer | no | Minimum number of replicas per object | +| pg_autoscale_mode | string | no | The automatic PG scaling mode of the pool. | +| pg_num | integer | no | Number of placement groups. | +| pg_num_min | integer | no | Minimal number of placement groups. | +| size | integer | no | Number of replicas per object | +| target_size | string | no | The estimated target size of the pool for the PG autoscaler. | +| target_size_ratio | number | no | The estimated target ratio of the pool for the PG autoscaler. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_certificates_acme_certificate.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_certificates_acme_certificate.md new file mode 100644 index 00000000000..894dff97d07 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_certificates_acme_certificate.md @@ -0,0 +1,80 @@ +# PUT /nodes/{node}/certificates/acme/certificate + +Renew existing certificate from CA. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| force | boolean | no | Force renewal even if expiry is more than 30 days away. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_config.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_config.md new file mode 100644 index 00000000000..b31f9963f7f --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_config.md @@ -0,0 +1,231 @@ +# PUT /nodes/{node}/config + +Set node configuration options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acme | string | no | Node specific ACME settings. | +| acmedomain[n] | string | no | ACME domain and validation plugin | +| ballooning-target | integer | no | RAM usage target for ballooning (in percent of total memory) | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| location | string | no | The location of the node. Overrides the default from the datacenter config. | +| startall-onboot-delay | integer | no | Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled. | +| wakeonlan | string | no | Node specific wake on LAN settings. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_disks_wipedisk.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_disks_wipedisk.md new file mode 100644 index 00000000000..3d903b66edb --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_disks_wipedisk.md @@ -0,0 +1,59 @@ +# PUT /nodes/{node}/disks/wipedisk + +Wipe a disk or partition. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | Block device name | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +Not specified. + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_dns.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_dns.md new file mode 100644 index 00000000000..80ea84fb603 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_dns.md @@ -0,0 +1,102 @@ +# PUT /nodes/{node}/dns + +Write DNS settings. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| search | string | yes | Search domain for host-name lookup. | +| dns1 | string | no | First name server IP address. | +| dns2 | string | no | Second name server IP address. | +| dns3 | string | no | Third name server IP address. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_firewall_options.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_firewall_options.md new file mode 100644 index 00000000000..42457de8be8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_firewall_options.md @@ -0,0 +1,289 @@ +# PUT /nodes/{node}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable host firewall rules. | +| log_level_forward | string | no | Log level for forwarded traffic. | +| log_level_in | string | no | Log level for incoming traffic. | +| log_level_out | string | no | Log level for outgoing traffic. | +| log_nf_conntrack | boolean | no | Enable logging of conntrack information. | +| ndp | boolean | no | Enable NDP (Neighbor Discovery Protocol). | +| nf_conntrack_allow_invalid | boolean | no | Allow invalid packets on connection tracking. | +| nf_conntrack_helpers | string | no | Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp | +| nf_conntrack_max | integer | no | Maximum number of tracked connections. | +| nf_conntrack_tcp_timeout_established | integer | no | Conntrack established timeout. | +| nf_conntrack_tcp_timeout_syn_recv | integer | no | Conntrack syn recv timeout. | +| nftables | boolean | no | Enable nftables based firewall (tech preview) | +| nosmurfs | boolean | no | Enable SMURFS filter. | +| protection_synflood | boolean | no | Enable synflood protection | +| protection_synflood_burst | integer | no | Synflood protection rate burst by ip src. | +| protection_synflood_rate | integer | no | Synflood protection rate syn/sec by ip src. | +| smurf_log_level | string | no | Log level for SMURFS filter. | +| tcp_flags_log_level | string | no | Log level for illegal tcp flags filter. | +| tcpflags | boolean | no | Filter illegal combinations of TCP flags. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_firewall_rules_pos.md new file mode 100644 index 00000000000..571ff0d66bf --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_firewall_rules_pos.md @@ -0,0 +1,225 @@ +# PUT /nodes/{node}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_config.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_config.md new file mode 100644 index 00000000000..8e433a0ca0b --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_config.md @@ -0,0 +1,734 @@ +# PUT /nodes/{node}/lxc/{vmid}/config + +Set container options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| arch | string | no | OS architecture type. | +| cmode | string | no | 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). | +| console | boolean | no | Attach a console device (/dev/console) to the container. | +| cores | integer | no | The number of cores assigned to the container. A container can use all available cores by default. | +| cpulimit | number | no | Limit of CPU usage. NOTE: If the computer has 2 CPUs, it has a total of '2' CPU time. Value '0' indicates no CPU limit. | +| cpuunits | integer | no | CPU weight for a container, will be clamped to [1, 10000] in cgroup v2. | +| debug | boolean | no | Try to be more verbose. For now this only enables debug log-level on start. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file. | +| dev[n] | string | no | Device to pass through to the container | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| entrypoint | string | no | Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH. | +| env | string | no | The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config. | +| features | string | no | Allow containers access to advanced features. | +| hookscript | string | no | Script that will be executed during various steps in the containers lifetime. | +| hostname | string | no | Set a host name for the container. | +| lock | string | no | Lock/unlock the container. | +| memory | integer | no | Amount of RAM for the container in MB. | +| mp[n] | string | no | Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume. | +| nameserver | string | no | Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| net[n] | string | no | Specifies network interfaces for the container. | +| onboot | boolean | no | Specifies whether a container will be started during system bootup. | +| ostype | string | no | 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. | +| protection | boolean | no | Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation. | +| revert | string | no | Revert a pending change. | +| rootfs | string | no | Use volume as container root. | +| searchdomain | string | no | Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver. | +| startup | string | no | 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. | +| swap | integer | no | Amount of SWAP for the container in MB. | +| tags | string | no | Tags of the Container. This is only meta information. | +| template | boolean | no | Enable/disable Template. | +| timezone | string | no | 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 | +| tty | integer | no | Specify the number of tty available to the container | +| unprivileged | boolean | no | 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.) | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_aliases_name.md new file mode 100644 index 00000000000..612f3b3ded3 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_aliases_name.md @@ -0,0 +1,118 @@ +# PUT /nodes/{node}/lxc/{vmid}/firewall/aliases/{name} + +Update IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing alias. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..dd2b8924e8c --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md @@ -0,0 +1,115 @@ +# PUT /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr} + +Update IP or Network settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_options.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_options.md new file mode 100644 index 00000000000..e44e8d66de7 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_options.md @@ -0,0 +1,199 @@ +# PUT /nodes/{node}/lxc/{vmid}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| dhcp | boolean | no | Enable DHCP. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable/disable firewall rules. | +| ipfilter | boolean | no | 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. | +| log_level_in | string | no | Log level for incoming traffic. | +| log_level_out | string | no | Log level for outgoing traffic. | +| macfilter | boolean | no | Enable/disable MAC address filter. | +| ndp | boolean | no | Enable NDP (Neighbor Discovery Protocol). | +| policy_in | string | no | Input policy. | +| policy_out | string | no | Output policy. | +| radv | boolean | no | Allow sending Router Advertisement. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_rules_pos.md new file mode 100644 index 00000000000..a2feb83ee06 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_firewall_rules_pos.md @@ -0,0 +1,234 @@ +# PUT /nodes/{node}/lxc/{vmid}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_resize.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_resize.md new file mode 100644 index 00000000000..1eb2a440120 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_resize.md @@ -0,0 +1,365 @@ +# PUT /nodes/{node}/lxc/{vmid}/resize + +Resize a container mount point. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | The disk you want to resize. | +| size | string | yes | 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. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ], + "any", + 1 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_snapshot_snapname_config.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_snapshot_snapname_config.md new file mode 100644 index 00000000000..87891c65fc8 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_lxc_vmid_snapshot_snapname_config.md @@ -0,0 +1,96 @@ +# PUT /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config + +Update snapshot metadata. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| description | string | no | A textual description or comment. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_network.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_network.md new file mode 100644 index 00000000000..97e40d3b449 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_network.md @@ -0,0 +1,80 @@ +# PUT /nodes/{node}/network + +Reload network configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| regenerate-frr | boolean | no | Whether FRR config generation should get skipped or not. | + +## Returns + +```json +{ + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_network_iface.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_network_iface.md new file mode 100644 index 00000000000..a5e28460042 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_network_iface.md @@ -0,0 +1,333 @@ +# PUT /nodes/{node}/network/{iface} + +Update network device configuration + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| iface | string | yes | Network interface name. | +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| type | string | yes | Network interface type | +| address | string | no | IP address. | +| address6 | string | no | IP address. | +| autostart | boolean | no | Automatically start interface on boot. | +| bond_mode | string | no | Bonding mode. | +| bond_xmit_hash_policy | string | no | Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. | +| bond-primary | string | no | Specify the primary interface for active-backup bond. | +| bridge_ports | string | no | Specify the interfaces you want to add to your bridge. | +| bridge_vids | string | no | Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware. | +| bridge_vlan_aware | boolean | no | Enable bridge vlan support. | +| cidr | string | no | IPv4 CIDR. | +| cidr6 | string | no | IPv6 CIDR. | +| comments | string | no | Comments | +| comments6 | string | no | Comments | +| delete | string | no | A list of settings you want to delete. | +| gateway | string | no | Default gateway address. | +| gateway6 | string | no | Default ipv6 gateway address. | +| mtu | integer | no | MTU. | +| netmask | string | no | Network mask. | +| netmask6 | integer | no | Network mask. | +| ovs_bonds | string | no | Specify the interfaces used by the bonding device. | +| ovs_bridge | string | no | The OVS bridge associated with a OVS port. This is required when you create an OVS port. | +| ovs_options | string | no | OVS interface options. | +| ovs_ports | string | no | Specify the interfaces you want to add to your bridge. | +| ovs_tag | integer | no | Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond) | +| slaves | string | no | Specify the interfaces used by the bonding device. | +| vlan-id | integer | no | vlan-id for a custom named vlan interface (ifupdown2 only). | +| vlan-raw-device | string | no | Specify the raw interface for the vlan interface. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_cloudinit.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_cloudinit.md new file mode 100644 index 00000000000..3bbbd6c1bce --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_cloudinit.md @@ -0,0 +1,80 @@ +# PUT /nodes/{node}/qemu/{vmid}/cloudinit + +Regenerate and change cloudinit config drive. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +None. + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Cloudinit" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_config.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_config.md new file mode 100644 index 00000000000..4181a3e01e0 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_config.md @@ -0,0 +1,2602 @@ +# PUT /nodes/{node}/qemu/{vmid}/config + +Set virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| acpi | boolean | no | Enable/disable ACPI. | +| affinity | string | no | List of host cores used to execute guest processes, for example: 0,5,8-11 | +| agent | string | no | Enable/disable communication with the QEMU Guest Agent and its properties. | +| allow-ksm | boolean | no | Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging). | +| amd-sev | string | no | Secure Encrypted Virtualization (SEV) features by AMD CPUs | +| arch | string | no | Virtual processor architecture. Defaults to the host architecture. | +| args | string | no | Arbitrary arguments passed to kvm. | +| audio0 | string | no | Configure a audio device, useful in combination with QXL/Spice. | +| autostart | boolean | no | Automatic restart after crash (currently ignored). | +| balloon | integer | no | 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. | +| bios | string | no | Select BIOS implementation. | +| boot | string | no | Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated. | +| bootdisk | string | no | Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead. | +| cdrom | string | no | This is an alias for option -ide2 | +| cicustom | string | no | cloud-init: Specify custom files to replace the automatically generated ones at start. | +| cipassword | string | no | 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. | +| citype | string | no | 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. | +| ciupgrade | boolean | no | cloud-init: do an automatic package upgrade after the first boot. | +| ciuser | string | no | cloud-init: User name to change ssh keys and password for instead of the image's configured default user. | +| cores | integer | no | The number of cores per socket. | +| cpu | string | no | Emulated CPU type. | +| cpulimit | number | no | Limit of CPU usage. | +| cpuunits | integer | no | CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2. | +| delete | string | no | A list of settings you want to delete. | +| description | string | no | Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| efidisk0 | string | no | 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. | +| force | boolean | no | 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. | +| freeze | boolean | no | Freeze CPU at startup (use 'c' monitor command to start execution). | +| hookscript | string | no | Script that will be executed during various steps in the vms lifetime. | +| hostpci[n] | string | no | Map host PCI devices into guest. | +| hotplug | string | no | 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. | +| hugepages | string | no | Enables hugepages memory. Sets 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. | +| ide[n] | string | no | 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. | +| intel-tdx | string | no | Trusted Domain Extension (TDX) features by Intel CPUs | +| ipconfig[n] | string | no | cloud-init: Specify IP addresses and gateways for the corresponding interface. IP addresses use CIDR notation, gateways are optional but need an IP of the same type specified. The special string 'dhcp' can be used for IP addresses to use DHCP, in which case no explicit gateway should be provided. For IPv6 the special string 'auto' can be used to use stateless autoconfiguration. This requires cloud-init 19.4 or newer. If cloud-init is enabled and neither an IPv4 nor an IPv6 address is specified, it defaults to using dhcp on IPv4. | +| ivshmem | string | no | Inter-VM shared memory. Useful for direct communication between VMs, or to the host. | +| keephugepages | boolean | no | Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts. | +| keyboard | string | no | Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. | +| kvm | boolean | no | Enable/disable KVM hardware virtualization. | +| localtime | boolean | no | Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS. | +| lock | string | no | Lock/unlock the VM. | +| machine | string | no | Specify the QEMU machine. | +| memory | string | no | Memory properties. | +| migrate_downtime | number | no | 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). | +| migrate_speed | integer | no | Set maximum speed (in MB/s) for migrations. Value 0 is no limit. | +| name | string | no | Set a name for the VM. Only used on the configuration web interface. | +| nameserver | string | no | 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. | +| net[n] | string | no | Specify network devices. | +| numa | boolean | no | Enable/disable NUMA. | +| numa[n] | string | no | NUMA topology. | +| onboot | boolean | no | Specifies whether a VM will be started during system bootup. | +| ostype | string | no | Specify guest operating system. | +| parallel[n] | string | no | Map host parallel devices (n is 0 to 2). | +| protection | boolean | no | Sets the protection flag of the VM. This will disable the remove VM and remove disk operations. | +| reboot | boolean | no | Allow reboot. If set to '0' the VM exit on reboot. | +| revert | string | no | Revert a pending change. | +| rng0 | string | no | Configure a VirtIO-based Random Number Generator. | +| sata[n] | string | no | 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. | +| scsi[n] | string | no | 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. | +| scsihw | string | no | SCSI controller model | +| searchdomain | string | no | 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. | +| serial[n] | string | no | Create a serial device inside the VM (n is 0 to 3) | +| shares | integer | no | 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. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | +| smbios1 | string | no | Specify SMBIOS type 1 fields. | +| smp | integer | no | The number of CPUs. Please use option -sockets instead. | +| sockets | integer | no | The number of CPU sockets. | +| spice_enhancements | string | no | Configure additional enhancements for SPICE. | +| sshkeys | string | no | cloud-init: Setup public SSH keys (one key per line, OpenSSH format). | +| startdate | string | no | 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'. | +| startup | string | no | 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. | +| tablet | boolean | no | Enable/disable the USB tablet device. | +| tags | string | no | Tags of the VM. This is only meta information. | +| tdf | boolean | no | Enable/disable time drift fix. | +| template | boolean | no | Enable/disable Template. | +| tpmstate0 | string | no | 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. | +| unused[n] | string | no | Reference to unused volumes. This is used internally, and should not be modified manually. | +| usb[n] | string | no | 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). | +| vcpus | integer | no | Number of hotplugged vcpus. | +| vga | string | no | Configure the VGA hardware. | +| virtio[n] | string | no | 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. | +| virtiofs[n] | string | no | Configuration for sharing a directory between host and guest using Virtio-fs. | +| vmgenid | string | no | Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly. | +| vmstatestorage | string | no | Default storage for VM state volumes/files. | +| watchdog | string | no | Create a virtual hardware watchdog device. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "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 + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_aliases_name.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_aliases_name.md new file mode 100644 index 00000000000..6dfd65cee15 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_aliases_name.md @@ -0,0 +1,118 @@ +# PUT /nodes/{node}/qemu/{vmid}/firewall/aliases/{name} + +Update IP or Network alias. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| name | string | yes | Alias name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| rename | string | no | Rename an existing alias. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md new file mode 100644 index 00000000000..f2acab25c45 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md @@ -0,0 +1,115 @@ +# PUT /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr} + +Update IP or Network settings + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| cidr | string | yes | Network/IP specification in CIDR format. | +| name | string | yes | IP set name. | +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| comment | string | no | | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| nomatch | boolean | no | | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_options.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_options.md new file mode 100644 index 00000000000..c4357c0d99d --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_options.md @@ -0,0 +1,199 @@ +# PUT /nodes/{node}/qemu/{vmid}/firewall/options + +Set Firewall options. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| delete | string | no | A list of settings you want to delete. | +| dhcp | boolean | no | Enable DHCP. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| enable | boolean | no | Enable/disable firewall rules. | +| ipfilter | boolean | no | 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. | +| log_level_in | string | no | Log level for incoming traffic. | +| log_level_out | string | no | Log level for outgoing traffic. | +| macfilter | boolean | no | Enable/disable MAC address filter. | +| ndp | boolean | no | Enable NDP (Neighbor Discovery Protocol). | +| policy_in | string | no | Input policy. | +| policy_out | string | no | Output policy. | +| radv | boolean | no | Allow sending Router Advertisement. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_rules_pos.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_rules_pos.md new file mode 100644 index 00000000000..da8639ff5a2 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_firewall_rules_pos.md @@ -0,0 +1,234 @@ +# PUT /nodes/{node}/qemu/{vmid}/firewall/rules/{pos} + +Modify rule data. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | +| pos | integer | no | Update rule at position . | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| action | string | no | Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name. | +| comment | string | no | Descriptive comment. | +| delete | string | no | A list of settings you want to delete. | +| dest | string | no | 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. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| dport | string | no | 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. | +| enable | integer | no | Flag to enable/disable a rule. | +| icmp-type | string | no | Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'. | +| iface | string | no | Network interface name. You have to use network configuration key names for VMs and containers ('net\d+'). Host related rules can use arbitrary strings. | +| log | string | no | Log level for firewall rule. | +| macro | string | no | Use predefined standard macro. | +| moveto | integer | no | Move rule to new position . Other arguments are ignored. | +| proto | string | no | IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'. | +| source | string | no | 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. | +| sport | string | no | 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. | +| type | string | no | Rule type. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Network" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_resize.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_resize.md new file mode 100644 index 00000000000..ee54168a670 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_resize.md @@ -0,0 +1,170 @@ +# PUT /nodes/{node}/qemu/{vmid}/resize + +Extend volume size. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| disk | string | yes | The disk you want to resize. | +| size | string | yes | 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. | +| digest | string | no | Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications. | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "description": "the task ID.", + "type": "string" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_sendkey.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_sendkey.md new file mode 100644 index 00000000000..dbf5ec9054a --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_sendkey.md @@ -0,0 +1,94 @@ +# PUT /nodes/{node}/qemu/{vmid}/sendkey + +Send key event to virtual machine. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| key | string | yes | The key (qemu monitor encoding). | +| skiplock | boolean | no | Ignore locks - only root is allowed to use this option. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Console" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_snapshot_snapname_config.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_snapshot_snapname_config.md new file mode 100644 index 00000000000..a809b264638 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_snapshot_snapname_config.md @@ -0,0 +1,96 @@ +# PUT /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config + +Update snapshot metadata. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| snapname | string | yes | The name of the snapshot. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| description | string | no | A textual description or comment. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Snapshot" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_unlink.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_unlink.md new file mode 100644 index 00000000000..302be281185 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_qemu_vmid_unlink.md @@ -0,0 +1,95 @@ +# PUT /nodes/{node}/qemu/{vmid}/unlink + +Unlink/delete disk images. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| vmid | integer | yes | The (unique) ID of the VM. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| idlist | string | yes | A list of disk IDs you want to delete. | +| force | boolean | no | 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. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/vms/{vmid}", + [ + "VM.Config.Disk" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_storage_storage_content_volume.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_storage_storage_content_volume.md new file mode 100644 index 00000000000..4ce61693093 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_storage_storage_content_volume.md @@ -0,0 +1,91 @@ +# PUT /nodes/{node}/storage/{storage}/content/{volume} + +Update volume attributes + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | +| volume | string | yes | Volume identifier | +| storage | string | no | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| notes | string | no | The new notes. | +| protected | boolean | no | Protection status. Currently only supported for backups. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "description": "You need read access for the volume.", + "user": "all" +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_subscription.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_subscription.md new file mode 100644 index 00000000000..db21ad69fd9 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_subscription.md @@ -0,0 +1,79 @@ +# PUT /nodes/{node}/subscription + +Set subscription key. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| key | string | yes | Proxmox VE subscription key | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_nodes_node_time.md b/docs/pve-api/markdown/endpoints/PUT_nodes_node_time.md new file mode 100644 index 00000000000..ffa838045c4 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_nodes_node_time.md @@ -0,0 +1,78 @@ +# PUT /nodes/{node}/time + +Set time zone. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| node | string | yes | The cluster node name. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| timezone | string | yes | Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/nodes/{node}", + [ + "Sys.Modify" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_pools.md b/docs/pve-api/markdown/endpoints/PUT_pools.md new file mode 100644 index 00000000000..f414287edbc --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_pools.md @@ -0,0 +1,109 @@ +# PUT /pools + +Update pool. + +## Path parameters + +None. + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | +| allow-move | boolean | no | Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one. | +| comment | string | no | | +| delete | boolean | no | Remove the passed VMIDs and/or storage IDs instead of adding them. | +| storage | string | no | List of storage IDs to add or remove from this pool. | +| vms | string | no | List of guest VMIDs to add or remove from this pool. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You also need the right to modify permissions on any object you add/delete." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_pools_poolid.md b/docs/pve-api/markdown/endpoints/PUT_pools_poolid.md new file mode 100644 index 00000000000..433bb15a8c5 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_pools_poolid.md @@ -0,0 +1,110 @@ +# PUT /pools/{poolid} + +Update pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead). + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| poolid | string | yes | | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| allow-move | boolean | no | Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one. | +| comment | string | no | | +| delete | boolean | no | Remove the passed VMIDs and/or storage IDs instead of adding them. | +| storage | string | no | List of storage IDs to add or remove from this pool. | +| vms | string | no | List of guest VMIDs to add or remove from this pool. | + +## Returns + +```json +{ + "type": "null" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/pool/{poolid}", + [ + "Pool.Allocate" + ] + ], + "description": "You also need the right to modify permissions on any object you add/delete." +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/endpoints/PUT_storage_storage.md b/docs/pve-api/markdown/endpoints/PUT_storage_storage.md new file mode 100644 index 00000000000..68464706134 --- /dev/null +++ b/docs/pve-api/markdown/endpoints/PUT_storage_storage.md @@ -0,0 +1,595 @@ +# PUT /storage/{storage} + +Update storage configuration. + +## Path parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| storage | string | yes | The storage identifier. | + +## Request parameters + +| Name | Type | Required | Description | +|---|---|---:|---| +| blocksize | string | no | ZFS block size | +| bwlimit | string | no | Set I/O bandwidth limit for various operations (in KiB/s). | +| comstar_hg | string | no | host group for comstar views | +| comstar_tg | string | no | target group for comstar views | +| content | string | no | Allowed content types. NOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs. | +| content-dirs | string | no | Overrides for default content type directories. | +| create-base-path | boolean | no | Create the base directory if it doesn't exist. | +| create-subdirs | boolean | no | Populate the directory with the default structure. | +| data-pool | string | no | Data Pool (for erasure coding only) | +| delete | string | no | A list of settings you want to delete. | +| digest | string | no | Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications. | +| disable | boolean | no | Flag to disable the storage. | +| domain | string | no | CIFS domain. | +| encryption-key | string | no | Encryption key. Use 'autogen' to generate one automatically without passphrase. | +| fingerprint | string | no | Certificate SHA 256 fingerprint. | +| format | string | no | Default image format. | +| fs-name | string | no | The Ceph filesystem name. | +| fuse | boolean | no | Mount CephFS through FUSE. | +| is_mountpoint | string | no | 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. | +| keyring | string | no | Client keyring contents (for external clusters). | +| krbd | boolean | no | Always access rbd through krbd kernel module. | +| lio_tpg | string | no | target portal group for Linux LIO targets | +| master-pubkey | string | no | Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup. | +| max-protected-backups | integer | no | Maximal number of protected backups per guest. Use '-1' for unlimited. | +| mkdir | boolean | no | 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. | +| monhost | string | no | IP addresses of monitors (for external clusters). | +| mountpoint | string | no | mount point | +| namespace | string | no | Namespace. | +| nocow | boolean | no | 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. | +| nodes | string | no | List of nodes for which the storage configuration applies. | +| nowritecache | boolean | no | disable write caching on the target | +| options | string | no | NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs') | +| password | string | no | Password for accessing the share/datastore. | +| pool | string | no | Pool. | +| port | integer | no | 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. | +| preallocation | string | no | Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. | +| prune-backups | string | no | 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. | +| saferemove | boolean | no | Zero-out data when removing LVs. | +| saferemove_throughput | string | no | Wipe throughput (cstream -t parameter value). | +| saferemove-stepsize | integer | no | Wipe step size in MiB. It will be capped to the maximum supported by the storage. | +| server | string | no | Server IP or DNS name. | +| shared | boolean | no | 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! | +| skip-cert-verification | boolean | no | Disable TLS certificate verification, only enable on fully trusted networks! | +| smbversion | string | no | SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. | +| snapshot-as-volume-chain | boolean | no | Enable support for creating storage-vendor agnostic snapshot through volume backing-chains. | +| sparse | boolean | no | use sparse volumes | +| subdir | string | no | Subdir to mount. | +| tagged_only | boolean | no | Only list logical volumes tagged with 'pve-vm-ID'. | +| username | string | no | RBD Id. | +| zfs-base-path | string | no | Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'. | + +## Returns + +```json +{ + "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" +} +``` + +## Permissions + +```json +{ + "check": [ + "perm", + "/storage", + [ + "Datastore.Allocate" + ] + ] +} +``` + +## Raw schema + +```json +{ + "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" + } +} +``` diff --git a/docs/pve-api/markdown/index.md b/docs/pve-api/markdown/index.md new file mode 100644 index 00000000000..aa233257dfd --- /dev/null +++ b/docs/pve-api/markdown/index.md @@ -0,0 +1,681 @@ +# Proxmox VE API Documentation + +Static documentation generated from Proxmox VE `apidoc.js`. + +| Method | Path | Summary | +|---|---|---| +| GET | `/access` | [index](endpoints/GET_access.md) | +| GET | `/access/acl` | [read_acl](endpoints/GET_access_acl.md) | +| PUT | `/access/acl` | [update_acl](endpoints/PUT_access_acl.md) | +| GET | `/access/domains` | [index](endpoints/GET_access_domains.md) | +| POST | `/access/domains` | [create](endpoints/POST_access_domains.md) | +| DELETE | `/access/domains/{realm}` | [delete](endpoints/DELETE_access_domains_realm.md) | +| GET | `/access/domains/{realm}` | [read](endpoints/GET_access_domains_realm.md) | +| PUT | `/access/domains/{realm}` | [update](endpoints/PUT_access_domains_realm.md) | +| POST | `/access/domains/{realm}/sync` | [sync](endpoints/POST_access_domains_realm_sync.md) | +| GET | `/access/groups` | [index](endpoints/GET_access_groups.md) | +| POST | `/access/groups` | [create_group](endpoints/POST_access_groups.md) | +| DELETE | `/access/groups/{groupid}` | [delete_group](endpoints/DELETE_access_groups_groupid.md) | +| GET | `/access/groups/{groupid}` | [read_group](endpoints/GET_access_groups_groupid.md) | +| PUT | `/access/groups/{groupid}` | [update_group](endpoints/PUT_access_groups_groupid.md) | +| GET | `/access/openid` | [index](endpoints/GET_access_openid.md) | +| POST | `/access/openid/auth-url` | [auth_url](endpoints/POST_access_openid_auth_url.md) | +| POST | `/access/openid/login` | [login](endpoints/POST_access_openid_login.md) | +| PUT | `/access/password` | [change_password](endpoints/PUT_access_password.md) | +| GET | `/access/permissions` | [permissions](endpoints/GET_access_permissions.md) | +| GET | `/access/roles` | [index](endpoints/GET_access_roles.md) | +| POST | `/access/roles` | [create_role](endpoints/POST_access_roles.md) | +| DELETE | `/access/roles/{roleid}` | [delete_role](endpoints/DELETE_access_roles_roleid.md) | +| GET | `/access/roles/{roleid}` | [read_role](endpoints/GET_access_roles_roleid.md) | +| PUT | `/access/roles/{roleid}` | [update_role](endpoints/PUT_access_roles_roleid.md) | +| GET | `/access/tfa` | [list_tfa](endpoints/GET_access_tfa.md) | +| GET | `/access/tfa/{userid}` | [list_user_tfa](endpoints/GET_access_tfa_userid.md) | +| POST | `/access/tfa/{userid}` | [add_tfa_entry](endpoints/POST_access_tfa_userid.md) | +| DELETE | `/access/tfa/{userid}/{id}` | [delete_tfa](endpoints/DELETE_access_tfa_userid_id.md) | +| GET | `/access/tfa/{userid}/{id}` | [get_tfa_entry](endpoints/GET_access_tfa_userid_id.md) | +| PUT | `/access/tfa/{userid}/{id}` | [update_tfa_entry](endpoints/PUT_access_tfa_userid_id.md) | +| GET | `/access/ticket` | [get_ticket](endpoints/GET_access_ticket.md) | +| POST | `/access/ticket` | [create_ticket](endpoints/POST_access_ticket.md) | +| GET | `/access/users` | [index](endpoints/GET_access_users.md) | +| POST | `/access/users` | [create_user](endpoints/POST_access_users.md) | +| DELETE | `/access/users/{userid}` | [delete_user](endpoints/DELETE_access_users_userid.md) | +| GET | `/access/users/{userid}` | [read_user](endpoints/GET_access_users_userid.md) | +| PUT | `/access/users/{userid}` | [update_user](endpoints/PUT_access_users_userid.md) | +| GET | `/access/users/{userid}/tfa` | [read_user_tfa_type](endpoints/GET_access_users_userid_tfa.md) | +| GET | `/access/users/{userid}/token` | [token_index](endpoints/GET_access_users_userid_token.md) | +| DELETE | `/access/users/{userid}/token/{tokenid}` | [remove_token](endpoints/DELETE_access_users_userid_token_tokenid.md) | +| GET | `/access/users/{userid}/token/{tokenid}` | [read_token](endpoints/GET_access_users_userid_token_tokenid.md) | +| POST | `/access/users/{userid}/token/{tokenid}` | [generate_token](endpoints/POST_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/token/{tokenid}` | [update_token_info](endpoints/PUT_access_users_userid_token_tokenid.md) | +| PUT | `/access/users/{userid}/unlock-tfa` | [unlock_tfa](endpoints/PUT_access_users_userid_unlock_tfa.md) | +| POST | `/access/vncticket` | [verify_vnc_ticket](endpoints/POST_access_vncticket.md) | +| GET | `/cluster` | [index](endpoints/GET_cluster.md) | +| GET | `/cluster/acme` | [index](endpoints/GET_cluster_acme.md) | +| GET | `/cluster/acme/account` | [account_index](endpoints/GET_cluster_acme_account.md) | +| POST | `/cluster/acme/account` | [register_account](endpoints/POST_cluster_acme_account.md) | +| DELETE | `/cluster/acme/account/{name}` | [deactivate_account](endpoints/DELETE_cluster_acme_account_name.md) | +| GET | `/cluster/acme/account/{name}` | [get_account](endpoints/GET_cluster_acme_account_name.md) | +| PUT | `/cluster/acme/account/{name}` | [update_account](endpoints/PUT_cluster_acme_account_name.md) | +| GET | `/cluster/acme/challenge-schema` | [challengeschema](endpoints/GET_cluster_acme_challenge_schema.md) | +| GET | `/cluster/acme/directories` | [get_directories](endpoints/GET_cluster_acme_directories.md) | +| GET | `/cluster/acme/meta` | [get_meta](endpoints/GET_cluster_acme_meta.md) | +| GET | `/cluster/acme/plugins` | [index](endpoints/GET_cluster_acme_plugins.md) | +| POST | `/cluster/acme/plugins` | [add_plugin](endpoints/POST_cluster_acme_plugins.md) | +| DELETE | `/cluster/acme/plugins/{id}` | [delete_plugin](endpoints/DELETE_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/plugins/{id}` | [get_plugin_config](endpoints/GET_cluster_acme_plugins_id.md) | +| PUT | `/cluster/acme/plugins/{id}` | [update_plugin](endpoints/PUT_cluster_acme_plugins_id.md) | +| GET | `/cluster/acme/tos` | [get_tos](endpoints/GET_cluster_acme_tos.md) | +| GET | `/cluster/backup` | [index](endpoints/GET_cluster_backup.md) | +| POST | `/cluster/backup` | [create_job](endpoints/POST_cluster_backup.md) | +| GET | `/cluster/backup-info` | [index](endpoints/GET_cluster_backup_info.md) | +| GET | `/cluster/backup-info/not-backed-up` | [get_guests_not_in_backup](endpoints/GET_cluster_backup_info_not_backed_up.md) | +| DELETE | `/cluster/backup/{id}` | [delete_job](endpoints/DELETE_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}` | [read_job](endpoints/GET_cluster_backup_id.md) | +| PUT | `/cluster/backup/{id}` | [update_job](endpoints/PUT_cluster_backup_id.md) | +| GET | `/cluster/backup/{id}/included_volumes` | [get_volume_backup_included](endpoints/GET_cluster_backup_id_included_volumes.md) | +| GET | `/cluster/bulk-action` | [index](endpoints/GET_cluster_bulk_action.md) | +| GET | `/cluster/bulk-action/guest` | [index](endpoints/GET_cluster_bulk_action_guest.md) | +| POST | `/cluster/bulk-action/guest/migrate` | [migrate](endpoints/POST_cluster_bulk_action_guest_migrate.md) | +| POST | `/cluster/bulk-action/guest/shutdown` | [shutdown](endpoints/POST_cluster_bulk_action_guest_shutdown.md) | +| POST | `/cluster/bulk-action/guest/start` | [start](endpoints/POST_cluster_bulk_action_guest_start.md) | +| POST | `/cluster/bulk-action/guest/suspend` | [suspend](endpoints/POST_cluster_bulk_action_guest_suspend.md) | +| GET | `/cluster/ceph` | [cephindex](endpoints/GET_cluster_ceph.md) | +| GET | `/cluster/ceph/flags` | [get_all_flags](endpoints/GET_cluster_ceph_flags.md) | +| PUT | `/cluster/ceph/flags` | [set_flags](endpoints/PUT_cluster_ceph_flags.md) | +| GET | `/cluster/ceph/flags/{flag}` | [get_flag](endpoints/GET_cluster_ceph_flags_flag.md) | +| PUT | `/cluster/ceph/flags/{flag}` | [update_flag](endpoints/PUT_cluster_ceph_flags_flag.md) | +| GET | `/cluster/ceph/metadata` | [metadata](endpoints/GET_cluster_ceph_metadata.md) | +| GET | `/cluster/ceph/status` | [status](endpoints/GET_cluster_ceph_status.md) | +| GET | `/cluster/config` | [index](endpoints/GET_cluster_config.md) | +| POST | `/cluster/config` | [create](endpoints/POST_cluster_config.md) | +| GET | `/cluster/config/apiversion` | [join_api_version](endpoints/GET_cluster_config_apiversion.md) | +| GET | `/cluster/config/join` | [join_info](endpoints/GET_cluster_config_join.md) | +| POST | `/cluster/config/join` | [join](endpoints/POST_cluster_config_join.md) | +| GET | `/cluster/config/nodes` | [nodes](endpoints/GET_cluster_config_nodes.md) | +| DELETE | `/cluster/config/nodes/{node}` | [delnode](endpoints/DELETE_cluster_config_nodes_node.md) | +| POST | `/cluster/config/nodes/{node}` | [addnode](endpoints/POST_cluster_config_nodes_node.md) | +| GET | `/cluster/config/qdevice` | [status](endpoints/GET_cluster_config_qdevice.md) | +| GET | `/cluster/config/totem` | [totem](endpoints/GET_cluster_config_totem.md) | +| GET | `/cluster/firewall` | [index](endpoints/GET_cluster_firewall.md) | +| GET | `/cluster/firewall/aliases` | [get_aliases](endpoints/GET_cluster_firewall_aliases.md) | +| POST | `/cluster/firewall/aliases` | [create_alias](endpoints/POST_cluster_firewall_aliases.md) | +| DELETE | `/cluster/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/aliases/{name}` | [read_alias](endpoints/GET_cluster_firewall_aliases_name.md) | +| PUT | `/cluster/firewall/aliases/{name}` | [update_alias](endpoints/PUT_cluster_firewall_aliases_name.md) | +| GET | `/cluster/firewall/groups` | [list_security_groups](endpoints/GET_cluster_firewall_groups.md) | +| POST | `/cluster/firewall/groups` | [create_security_group](endpoints/POST_cluster_firewall_groups.md) | +| DELETE | `/cluster/firewall/groups/{group}` | [delete_security_group](endpoints/DELETE_cluster_firewall_groups_group.md) | +| GET | `/cluster/firewall/groups/{group}` | [get_rules](endpoints/GET_cluster_firewall_groups_group.md) | +| POST | `/cluster/firewall/groups/{group}` | [create_rule](endpoints/POST_cluster_firewall_groups_group.md) | +| DELETE | `/cluster/firewall/groups/{group}/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/groups/{group}/{pos}` | [get_rule](endpoints/GET_cluster_firewall_groups_group_pos.md) | +| PUT | `/cluster/firewall/groups/{group}/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_groups_group_pos.md) | +| GET | `/cluster/firewall/ipset` | [ipset_index](endpoints/GET_cluster_firewall_ipset.md) | +| POST | `/cluster/firewall/ipset` | [create_ipset](endpoints/POST_cluster_firewall_ipset.md) | +| DELETE | `/cluster/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_cluster_firewall_ipset_name.md) | +| GET | `/cluster/firewall/ipset/{name}` | [get_ipset](endpoints/GET_cluster_firewall_ipset_name.md) | +| POST | `/cluster/firewall/ipset/{name}` | [create_ip](endpoints/POST_cluster_firewall_ipset_name.md) | +| DELETE | `/cluster/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_cluster_firewall_ipset_name_cidr.md) | +| PUT | `/cluster/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_cluster_firewall_ipset_name_cidr.md) | +| GET | `/cluster/firewall/macros` | [get_macros](endpoints/GET_cluster_firewall_macros.md) | +| GET | `/cluster/firewall/options` | [get_options](endpoints/GET_cluster_firewall_options.md) | +| PUT | `/cluster/firewall/options` | [set_options](endpoints/PUT_cluster_firewall_options.md) | +| GET | `/cluster/firewall/refs` | [refs](endpoints/GET_cluster_firewall_refs.md) | +| GET | `/cluster/firewall/rules` | [get_rules](endpoints/GET_cluster_firewall_rules.md) | +| POST | `/cluster/firewall/rules` | [create_rule](endpoints/POST_cluster_firewall_rules.md) | +| DELETE | `/cluster/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_firewall_rules_pos.md) | +| GET | `/cluster/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_firewall_rules_pos.md) | +| PUT | `/cluster/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_firewall_rules_pos.md) | +| GET | `/cluster/ha` | [index](endpoints/GET_cluster_ha.md) | +| GET | `/cluster/ha/groups` | [index](endpoints/GET_cluster_ha_groups.md) | +| POST | `/cluster/ha/groups` | [create](endpoints/POST_cluster_ha_groups.md) | +| DELETE | `/cluster/ha/groups/{group}` | [delete](endpoints/DELETE_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/groups/{group}` | [read](endpoints/GET_cluster_ha_groups_group.md) | +| PUT | `/cluster/ha/groups/{group}` | [update](endpoints/PUT_cluster_ha_groups_group.md) | +| GET | `/cluster/ha/resources` | [index](endpoints/GET_cluster_ha_resources.md) | +| POST | `/cluster/ha/resources` | [create](endpoints/POST_cluster_ha_resources.md) | +| DELETE | `/cluster/ha/resources/{sid}` | [delete](endpoints/DELETE_cluster_ha_resources_sid.md) | +| GET | `/cluster/ha/resources/{sid}` | [read](endpoints/GET_cluster_ha_resources_sid.md) | +| PUT | `/cluster/ha/resources/{sid}` | [update](endpoints/PUT_cluster_ha_resources_sid.md) | +| POST | `/cluster/ha/resources/{sid}/migrate` | [migrate](endpoints/POST_cluster_ha_resources_sid_migrate.md) | +| POST | `/cluster/ha/resources/{sid}/relocate` | [relocate](endpoints/POST_cluster_ha_resources_sid_relocate.md) | +| GET | `/cluster/ha/rules` | [index](endpoints/GET_cluster_ha_rules.md) | +| POST | `/cluster/ha/rules` | [create_rule](endpoints/POST_cluster_ha_rules.md) | +| DELETE | `/cluster/ha/rules/{rule}` | [delete_rule](endpoints/DELETE_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/rules/{rule}` | [read_rule](endpoints/GET_cluster_ha_rules_rule.md) | +| PUT | `/cluster/ha/rules/{rule}` | [update_rule](endpoints/PUT_cluster_ha_rules_rule.md) | +| GET | `/cluster/ha/status` | [index](endpoints/GET_cluster_ha_status.md) | +| POST | `/cluster/ha/status/arm-ha` | [arm-ha](endpoints/POST_cluster_ha_status_arm_ha.md) | +| GET | `/cluster/ha/status/current` | [status](endpoints/GET_cluster_ha_status_current.md) | +| POST | `/cluster/ha/status/disarm-ha` | [disarm-ha](endpoints/POST_cluster_ha_status_disarm_ha.md) | +| GET | `/cluster/ha/status/manager_status` | [manager_status](endpoints/GET_cluster_ha_status_manager_status.md) | +| GET | `/cluster/jobs` | [index](endpoints/GET_cluster_jobs.md) | +| GET | `/cluster/jobs/realm-sync` | [syncjob_index](endpoints/GET_cluster_jobs_realm_sync.md) | +| DELETE | `/cluster/jobs/realm-sync/{id}` | [delete_job](endpoints/DELETE_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/realm-sync/{id}` | [read_job](endpoints/GET_cluster_jobs_realm_sync_id.md) | +| POST | `/cluster/jobs/realm-sync/{id}` | [create_job](endpoints/POST_cluster_jobs_realm_sync_id.md) | +| PUT | `/cluster/jobs/realm-sync/{id}` | [update_job](endpoints/PUT_cluster_jobs_realm_sync_id.md) | +| GET | `/cluster/jobs/schedule-analyze` | [schedule-analyze](endpoints/GET_cluster_jobs_schedule_analyze.md) | +| GET | `/cluster/log` | [log](endpoints/GET_cluster_log.md) | +| GET | `/cluster/mapping` | [index](endpoints/GET_cluster_mapping.md) | +| GET | `/cluster/mapping/dir` | [index](endpoints/GET_cluster_mapping_dir.md) | +| POST | `/cluster/mapping/dir` | [create](endpoints/POST_cluster_mapping_dir.md) | +| DELETE | `/cluster/mapping/dir/{id}` | [delete](endpoints/DELETE_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/dir/{id}` | [get](endpoints/GET_cluster_mapping_dir_id.md) | +| PUT | `/cluster/mapping/dir/{id}` | [update](endpoints/PUT_cluster_mapping_dir_id.md) | +| GET | `/cluster/mapping/pci` | [index](endpoints/GET_cluster_mapping_pci.md) | +| POST | `/cluster/mapping/pci` | [create](endpoints/POST_cluster_mapping_pci.md) | +| DELETE | `/cluster/mapping/pci/{id}` | [delete](endpoints/DELETE_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/pci/{id}` | [get](endpoints/GET_cluster_mapping_pci_id.md) | +| PUT | `/cluster/mapping/pci/{id}` | [update](endpoints/PUT_cluster_mapping_pci_id.md) | +| GET | `/cluster/mapping/usb` | [index](endpoints/GET_cluster_mapping_usb.md) | +| POST | `/cluster/mapping/usb` | [create](endpoints/POST_cluster_mapping_usb.md) | +| DELETE | `/cluster/mapping/usb/{id}` | [delete](endpoints/DELETE_cluster_mapping_usb_id.md) | +| GET | `/cluster/mapping/usb/{id}` | [get](endpoints/GET_cluster_mapping_usb_id.md) | +| PUT | `/cluster/mapping/usb/{id}` | [update](endpoints/PUT_cluster_mapping_usb_id.md) | +| GET | `/cluster/metrics` | [index](endpoints/GET_cluster_metrics.md) | +| GET | `/cluster/metrics/export` | [export](endpoints/GET_cluster_metrics_export.md) | +| GET | `/cluster/metrics/server` | [server_index](endpoints/GET_cluster_metrics_server.md) | +| DELETE | `/cluster/metrics/server/{id}` | [delete](endpoints/DELETE_cluster_metrics_server_id.md) | +| GET | `/cluster/metrics/server/{id}` | [read](endpoints/GET_cluster_metrics_server_id.md) | +| POST | `/cluster/metrics/server/{id}` | [create](endpoints/POST_cluster_metrics_server_id.md) | +| PUT | `/cluster/metrics/server/{id}` | [update](endpoints/PUT_cluster_metrics_server_id.md) | +| GET | `/cluster/nextid` | [nextid](endpoints/GET_cluster_nextid.md) | +| GET | `/cluster/notifications` | [index](endpoints/GET_cluster_notifications.md) | +| GET | `/cluster/notifications/endpoints` | [endpoints_index](endpoints/GET_cluster_notifications_endpoints.md) | +| GET | `/cluster/notifications/endpoints/gotify` | [get_gotify_endpoints](endpoints/GET_cluster_notifications_endpoints_gotify.md) | +| POST | `/cluster/notifications/endpoints/gotify` | [create_gotify_endpoint](endpoints/POST_cluster_notifications_endpoints_gotify.md) | +| DELETE | `/cluster/notifications/endpoints/gotify/{name}` | [delete_gotify_endpoint](endpoints/DELETE_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/gotify/{name}` | [get_gotify_endpoint](endpoints/GET_cluster_notifications_endpoints_gotify_name.md) | +| PUT | `/cluster/notifications/endpoints/gotify/{name}` | [update_gotify_endpoint](endpoints/PUT_cluster_notifications_endpoints_gotify_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail` | [get_sendmail_endpoints](endpoints/GET_cluster_notifications_endpoints_sendmail.md) | +| POST | `/cluster/notifications/endpoints/sendmail` | [create_sendmail_endpoint](endpoints/POST_cluster_notifications_endpoints_sendmail.md) | +| DELETE | `/cluster/notifications/endpoints/sendmail/{name}` | [delete_sendmail_endpoint](endpoints/DELETE_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/sendmail/{name}` | [get_sendmail_endpoint](endpoints/GET_cluster_notifications_endpoints_sendmail_name.md) | +| PUT | `/cluster/notifications/endpoints/sendmail/{name}` | [update_sendmail_endpoint](endpoints/PUT_cluster_notifications_endpoints_sendmail_name.md) | +| GET | `/cluster/notifications/endpoints/smtp` | [get_smtp_endpoints](endpoints/GET_cluster_notifications_endpoints_smtp.md) | +| POST | `/cluster/notifications/endpoints/smtp` | [create_smtp_endpoint](endpoints/POST_cluster_notifications_endpoints_smtp.md) | +| DELETE | `/cluster/notifications/endpoints/smtp/{name}` | [delete_smtp_endpoint](endpoints/DELETE_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/smtp/{name}` | [get_smtp_endpoint](endpoints/GET_cluster_notifications_endpoints_smtp_name.md) | +| PUT | `/cluster/notifications/endpoints/smtp/{name}` | [update_smtp_endpoint](endpoints/PUT_cluster_notifications_endpoints_smtp_name.md) | +| GET | `/cluster/notifications/endpoints/webhook` | [get_webhook_endpoints](endpoints/GET_cluster_notifications_endpoints_webhook.md) | +| POST | `/cluster/notifications/endpoints/webhook` | [create_webhook_endpoint](endpoints/POST_cluster_notifications_endpoints_webhook.md) | +| DELETE | `/cluster/notifications/endpoints/webhook/{name}` | [delete_webhook_endpoint](endpoints/DELETE_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/endpoints/webhook/{name}` | [get_webhook_endpoint](endpoints/GET_cluster_notifications_endpoints_webhook_name.md) | +| PUT | `/cluster/notifications/endpoints/webhook/{name}` | [update_webhook_endpoint](endpoints/PUT_cluster_notifications_endpoints_webhook_name.md) | +| GET | `/cluster/notifications/matcher-field-values` | [get_matcher_field_values](endpoints/GET_cluster_notifications_matcher_field_values.md) | +| GET | `/cluster/notifications/matcher-fields` | [get_matcher_fields](endpoints/GET_cluster_notifications_matcher_fields.md) | +| GET | `/cluster/notifications/matchers` | [get_matchers](endpoints/GET_cluster_notifications_matchers.md) | +| POST | `/cluster/notifications/matchers` | [create_matcher](endpoints/POST_cluster_notifications_matchers.md) | +| DELETE | `/cluster/notifications/matchers/{name}` | [delete_matcher](endpoints/DELETE_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/matchers/{name}` | [get_matcher](endpoints/GET_cluster_notifications_matchers_name.md) | +| PUT | `/cluster/notifications/matchers/{name}` | [update_matcher](endpoints/PUT_cluster_notifications_matchers_name.md) | +| GET | `/cluster/notifications/targets` | [get_all_targets](endpoints/GET_cluster_notifications_targets.md) | +| POST | `/cluster/notifications/targets/{name}/test` | [test_target](endpoints/POST_cluster_notifications_targets_name_test.md) | +| GET | `/cluster/options` | [get_options](endpoints/GET_cluster_options.md) | +| PUT | `/cluster/options` | [set_options](endpoints/PUT_cluster_options.md) | +| GET | `/cluster/qemu` | [index](endpoints/GET_cluster_qemu.md) | +| GET | `/cluster/qemu/cpu-flags` | [index](endpoints/GET_cluster_qemu_cpu_flags.md) | +| GET | `/cluster/qemu/custom-cpu-models` | [config](endpoints/GET_cluster_qemu_custom_cpu_models.md) | +| POST | `/cluster/qemu/custom-cpu-models` | [create](endpoints/POST_cluster_qemu_custom_cpu_models.md) | +| DELETE | `/cluster/qemu/custom-cpu-models/{cputype}` | [delete](endpoints/DELETE_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/qemu/custom-cpu-models/{cputype}` | [info](endpoints/GET_cluster_qemu_custom_cpu_models_cputype.md) | +| PUT | `/cluster/qemu/custom-cpu-models/{cputype}` | [update](endpoints/PUT_cluster_qemu_custom_cpu_models_cputype.md) | +| GET | `/cluster/replication` | [index](endpoints/GET_cluster_replication.md) | +| POST | `/cluster/replication` | [create](endpoints/POST_cluster_replication.md) | +| DELETE | `/cluster/replication/{id}` | [delete](endpoints/DELETE_cluster_replication_id.md) | +| GET | `/cluster/replication/{id}` | [read](endpoints/GET_cluster_replication_id.md) | +| PUT | `/cluster/replication/{id}` | [update](endpoints/PUT_cluster_replication_id.md) | +| GET | `/cluster/resources` | [resources](endpoints/GET_cluster_resources.md) | +| GET | `/cluster/sdn` | [index](endpoints/GET_cluster_sdn.md) | +| PUT | `/cluster/sdn` | [reload](endpoints/PUT_cluster_sdn.md) | +| GET | `/cluster/sdn/controllers` | [index](endpoints/GET_cluster_sdn_controllers.md) | +| POST | `/cluster/sdn/controllers` | [create](endpoints/POST_cluster_sdn_controllers.md) | +| DELETE | `/cluster/sdn/controllers/{controller}` | [delete](endpoints/DELETE_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/controllers/{controller}` | [read](endpoints/GET_cluster_sdn_controllers_controller.md) | +| PUT | `/cluster/sdn/controllers/{controller}` | [update](endpoints/PUT_cluster_sdn_controllers_controller.md) | +| GET | `/cluster/sdn/dns` | [index](endpoints/GET_cluster_sdn_dns.md) | +| POST | `/cluster/sdn/dns` | [create](endpoints/POST_cluster_sdn_dns.md) | +| DELETE | `/cluster/sdn/dns/{dns}` | [delete](endpoints/DELETE_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dns/{dns}` | [read](endpoints/GET_cluster_sdn_dns_dns.md) | +| PUT | `/cluster/sdn/dns/{dns}` | [update](endpoints/PUT_cluster_sdn_dns_dns.md) | +| GET | `/cluster/sdn/dry-run` | [dry-run](endpoints/GET_cluster_sdn_dry_run.md) | +| GET | `/cluster/sdn/fabrics` | [index](endpoints/GET_cluster_sdn_fabrics.md) | +| GET | `/cluster/sdn/fabrics/all` | [list_all](endpoints/GET_cluster_sdn_fabrics_all.md) | +| GET | `/cluster/sdn/fabrics/fabric` | [index](endpoints/GET_cluster_sdn_fabrics_fabric.md) | +| POST | `/cluster/sdn/fabrics/fabric` | [add_fabric](endpoints/POST_cluster_sdn_fabrics_fabric.md) | +| DELETE | `/cluster/sdn/fabrics/fabric/{id}` | [delete_fabric](endpoints/DELETE_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/fabric/{id}` | [get_fabric](endpoints/GET_cluster_sdn_fabrics_fabric_id.md) | +| PUT | `/cluster/sdn/fabrics/fabric/{id}` | [update_fabric](endpoints/PUT_cluster_sdn_fabrics_fabric_id.md) | +| GET | `/cluster/sdn/fabrics/node` | [list_nodes](endpoints/GET_cluster_sdn_fabrics_node.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}` | [list_nodes_fabric](endpoints/GET_cluster_sdn_fabrics_node_fabric_id.md) | +| POST | `/cluster/sdn/fabrics/node/{fabric_id}` | [add_node](endpoints/POST_cluster_sdn_fabrics_node_fabric_id.md) | +| DELETE | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [delete_node](endpoints/DELETE_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [get_node](endpoints/GET_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| PUT | `/cluster/sdn/fabrics/node/{fabric_id}/{node_id}` | [update_node](endpoints/PUT_cluster_sdn_fabrics_node_fabric_id_node_id.md) | +| GET | `/cluster/sdn/ipams` | [index](endpoints/GET_cluster_sdn_ipams.md) | +| POST | `/cluster/sdn/ipams` | [create](endpoints/POST_cluster_sdn_ipams.md) | +| DELETE | `/cluster/sdn/ipams/{ipam}` | [delete](endpoints/DELETE_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}` | [read](endpoints/GET_cluster_sdn_ipams_ipam.md) | +| PUT | `/cluster/sdn/ipams/{ipam}` | [update](endpoints/PUT_cluster_sdn_ipams_ipam.md) | +| GET | `/cluster/sdn/ipams/{ipam}/status` | [ipamindex](endpoints/GET_cluster_sdn_ipams_ipam_status.md) | +| DELETE | `/cluster/sdn/lock` | [release_lock](endpoints/DELETE_cluster_sdn_lock.md) | +| POST | `/cluster/sdn/lock` | [lock](endpoints/POST_cluster_sdn_lock.md) | +| GET | `/cluster/sdn/prefix-lists` | [list_prefix_lists](endpoints/GET_cluster_sdn_prefix_lists.md) | +| POST | `/cluster/sdn/prefix-lists` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}` | [delete_prefix_list](endpoints/DELETE_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}` | [get_prefix_list](endpoints/GET_cluster_sdn_prefix_lists_id.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}` | [update_prefix_list](endpoints/PUT_cluster_sdn_prefix_lists_id.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries` | [get_prefix_list_entries](endpoints/GET_cluster_sdn_prefix_lists_id_entries.md) | +| POST | `/cluster/sdn/prefix-lists/{id}/entries` | [create_prefix_list_entry](endpoints/POST_cluster_sdn_prefix_lists_id_entries.md) | +| DELETE | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [delete_prefix_list_entry](endpoints/DELETE_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| GET | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [get_prefix_list_entry](endpoints/GET_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| PUT | `/cluster/sdn/prefix-lists/{id}/entries/{url_seq}` | [update_prefix_list_entry](endpoints/PUT_cluster_sdn_prefix_lists_id_entries_url_seq.md) | +| POST | `/cluster/sdn/rollback` | [rollback](endpoints/POST_cluster_sdn_rollback.md) | +| GET | `/cluster/sdn/route-maps` | [list_route_maps](endpoints/GET_cluster_sdn_route_maps.md) | +| GET | `/cluster/sdn/route-maps/entries` | [list_route_map_entries](endpoints/GET_cluster_sdn_route_maps_entries.md) | +| POST | `/cluster/sdn/route-maps/entries` | [create_route_map_entry](endpoints/POST_cluster_sdn_route_maps_entries.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}` | [list_route_map_entries_for_route_map](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id.md) | +| DELETE | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [delete_route_map_entry](endpoints/DELETE_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [get_route_map_entry](endpoints/GET_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| PUT | `/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}` | [update_route_map_entry](endpoints/PUT_cluster_sdn_route_maps_entries_route_map_id_entry_order.md) | +| GET | `/cluster/sdn/vnets` | [index](endpoints/GET_cluster_sdn_vnets.md) | +| POST | `/cluster/sdn/vnets` | [create](endpoints/POST_cluster_sdn_vnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall` | [index](endpoints/GET_cluster_sdn_vnets_vnet_firewall.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/options` | [get_options](endpoints/GET_cluster_sdn_vnets_vnet_firewall_options.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/options` | [set_options](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_options.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [get_rules](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules.md) | +| POST | `/cluster/sdn/vnets/{vnet}/firewall/rules` | [create_rule](endpoints/POST_cluster_sdn_vnets_vnet_firewall_rules.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| GET | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [get_rule](endpoints/GET_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_cluster_sdn_vnets_vnet_firewall_rules_pos.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/ips` | [ipdelete](endpoints/DELETE_cluster_sdn_vnets_vnet_ips.md) | +| POST | `/cluster/sdn/vnets/{vnet}/ips` | [ipcreate](endpoints/POST_cluster_sdn_vnets_vnet_ips.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/ips` | [ipupdate](endpoints/PUT_cluster_sdn_vnets_vnet_ips.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets` | [index](endpoints/GET_cluster_sdn_vnets_vnet_subnets.md) | +| POST | `/cluster/sdn/vnets/{vnet}/subnets` | [create](endpoints/POST_cluster_sdn_vnets_vnet_subnets.md) | +| DELETE | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [delete](endpoints/DELETE_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [read](endpoints/GET_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| PUT | `/cluster/sdn/vnets/{vnet}/subnets/{subnet}` | [update](endpoints/PUT_cluster_sdn_vnets_vnet_subnets_subnet.md) | +| GET | `/cluster/sdn/zones` | [index](endpoints/GET_cluster_sdn_zones.md) | +| POST | `/cluster/sdn/zones` | [create](endpoints/POST_cluster_sdn_zones.md) | +| DELETE | `/cluster/sdn/zones/{zone}` | [delete](endpoints/DELETE_cluster_sdn_zones_zone.md) | +| GET | `/cluster/sdn/zones/{zone}` | [read](endpoints/GET_cluster_sdn_zones_zone.md) | +| PUT | `/cluster/sdn/zones/{zone}` | [update](endpoints/PUT_cluster_sdn_zones_zone.md) | +| GET | `/cluster/status` | [get_status](endpoints/GET_cluster_status.md) | +| GET | `/cluster/tasks` | [tasks](endpoints/GET_cluster_tasks.md) | +| GET | `/nodes` | [index](endpoints/GET_nodes.md) | +| GET | `/nodes/{node}` | [index](endpoints/GET_nodes_node.md) | +| GET | `/nodes/{node}/aplinfo` | [aplinfo](endpoints/GET_nodes_node_aplinfo.md) | +| POST | `/nodes/{node}/aplinfo` | [apl_download](endpoints/POST_nodes_node_aplinfo.md) | +| GET | `/nodes/{node}/apt` | [index](endpoints/GET_nodes_node_apt.md) | +| GET | `/nodes/{node}/apt/changelog` | [changelog](endpoints/GET_nodes_node_apt_changelog.md) | +| GET | `/nodes/{node}/apt/repositories` | [repositories](endpoints/GET_nodes_node_apt_repositories.md) | +| POST | `/nodes/{node}/apt/repositories` | [change_repository](endpoints/POST_nodes_node_apt_repositories.md) | +| PUT | `/nodes/{node}/apt/repositories` | [add_repository](endpoints/PUT_nodes_node_apt_repositories.md) | +| GET | `/nodes/{node}/apt/update` | [list_updates](endpoints/GET_nodes_node_apt_update.md) | +| POST | `/nodes/{node}/apt/update` | [update_database](endpoints/POST_nodes_node_apt_update.md) | +| GET | `/nodes/{node}/apt/versions` | [versions](endpoints/GET_nodes_node_apt_versions.md) | +| GET | `/nodes/{node}/capabilities` | [index](endpoints/GET_nodes_node_capabilities.md) | +| GET | `/nodes/{node}/capabilities/qemu` | [qemu_caps_index](endpoints/GET_nodes_node_capabilities_qemu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu-flags` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu_flags.md) | +| GET | `/nodes/{node}/capabilities/qemu/machines` | [types](endpoints/GET_nodes_node_capabilities_qemu_machines.md) | +| GET | `/nodes/{node}/capabilities/qemu/migration` | [capabilities](endpoints/GET_nodes_node_capabilities_qemu_migration.md) | +| GET | `/nodes/{node}/ceph` | [index](endpoints/GET_nodes_node_ceph.md) | +| GET | `/nodes/{node}/ceph/cfg` | [index](endpoints/GET_nodes_node_ceph_cfg.md) | +| GET | `/nodes/{node}/ceph/cfg/db` | [db](endpoints/GET_nodes_node_ceph_cfg_db.md) | +| GET | `/nodes/{node}/ceph/cfg/raw` | [raw](endpoints/GET_nodes_node_ceph_cfg_raw.md) | +| GET | `/nodes/{node}/ceph/cfg/value` | [value](endpoints/GET_nodes_node_ceph_cfg_value.md) | +| GET | `/nodes/{node}/ceph/cmd-safety` | [cmd_safety](endpoints/GET_nodes_node_ceph_cmd_safety.md) | +| GET | `/nodes/{node}/ceph/crush` | [crush](endpoints/GET_nodes_node_ceph_crush.md) | +| GET | `/nodes/{node}/ceph/fs` | [index](endpoints/GET_nodes_node_ceph_fs.md) | +| DELETE | `/nodes/{node}/ceph/fs/{name}` | [destroyfs](endpoints/DELETE_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/fs/{name}` | [createfs](endpoints/POST_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/init` | [init](endpoints/POST_nodes_node_ceph_init.md) | +| GET | `/nodes/{node}/ceph/log` | [log](endpoints/GET_nodes_node_ceph_log.md) | +| GET | `/nodes/{node}/ceph/mds` | [index](endpoints/GET_nodes_node_ceph_mds.md) | +| DELETE | `/nodes/{node}/ceph/mds/{name}` | [destroymds](endpoints/DELETE_nodes_node_ceph_mds_name.md) | +| POST | `/nodes/{node}/ceph/mds/{name}` | [createmds](endpoints/POST_nodes_node_ceph_mds_name.md) | +| GET | `/nodes/{node}/ceph/mgr` | [index](endpoints/GET_nodes_node_ceph_mgr.md) | +| DELETE | `/nodes/{node}/ceph/mgr/{id}` | [destroymgr](endpoints/DELETE_nodes_node_ceph_mgr_id.md) | +| POST | `/nodes/{node}/ceph/mgr/{id}` | [createmgr](endpoints/POST_nodes_node_ceph_mgr_id.md) | +| GET | `/nodes/{node}/ceph/mon` | [listmon](endpoints/GET_nodes_node_ceph_mon.md) | +| DELETE | `/nodes/{node}/ceph/mon/{monid}` | [destroymon](endpoints/DELETE_nodes_node_ceph_mon_monid.md) | +| POST | `/nodes/{node}/ceph/mon/{monid}` | [createmon](endpoints/POST_nodes_node_ceph_mon_monid.md) | +| GET | `/nodes/{node}/ceph/osd` | [index](endpoints/GET_nodes_node_ceph_osd.md) | +| POST | `/nodes/{node}/ceph/osd` | [createosd](endpoints/POST_nodes_node_ceph_osd.md) | +| DELETE | `/nodes/{node}/ceph/osd/{osdid}` | [destroyosd](endpoints/DELETE_nodes_node_ceph_osd_osdid.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}` | [osdindex](endpoints/GET_nodes_node_ceph_osd_osdid.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/in` | [in](endpoints/POST_nodes_node_ceph_osd_osdid_in.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/lv-info` | [osdvolume](endpoints/GET_nodes_node_ceph_osd_osdid_lv_info.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/metadata` | [osddetails](endpoints/GET_nodes_node_ceph_osd_osdid_metadata.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/out` | [out](endpoints/POST_nodes_node_ceph_osd_osdid_out.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/scrub` | [scrub](endpoints/POST_nodes_node_ceph_osd_osdid_scrub.md) | +| GET | `/nodes/{node}/ceph/pool` | [lspools](endpoints/GET_nodes_node_ceph_pool.md) | +| POST | `/nodes/{node}/ceph/pool` | [createpool](endpoints/POST_nodes_node_ceph_pool.md) | +| DELETE | `/nodes/{node}/ceph/pool/{name}` | [destroypool](endpoints/DELETE_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}` | [poolindex](endpoints/GET_nodes_node_ceph_pool_name.md) | +| PUT | `/nodes/{node}/ceph/pool/{name}` | [setpool](endpoints/PUT_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}/status` | [getpool](endpoints/GET_nodes_node_ceph_pool_name_status.md) | +| POST | `/nodes/{node}/ceph/restart` | [restart](endpoints/POST_nodes_node_ceph_restart.md) | +| GET | `/nodes/{node}/ceph/rules` | [rules](endpoints/GET_nodes_node_ceph_rules.md) | +| POST | `/nodes/{node}/ceph/start` | [start](endpoints/POST_nodes_node_ceph_start.md) | +| GET | `/nodes/{node}/ceph/status` | [status](endpoints/GET_nodes_node_ceph_status.md) | +| POST | `/nodes/{node}/ceph/stop` | [stop](endpoints/POST_nodes_node_ceph_stop.md) | +| GET | `/nodes/{node}/certificates` | [index](endpoints/GET_nodes_node_certificates.md) | +| GET | `/nodes/{node}/certificates/acme` | [index](endpoints/GET_nodes_node_certificates_acme.md) | +| DELETE | `/nodes/{node}/certificates/acme/certificate` | [revoke_certificate](endpoints/DELETE_nodes_node_certificates_acme_certificate.md) | +| POST | `/nodes/{node}/certificates/acme/certificate` | [new_certificate](endpoints/POST_nodes_node_certificates_acme_certificate.md) | +| PUT | `/nodes/{node}/certificates/acme/certificate` | [renew_certificate](endpoints/PUT_nodes_node_certificates_acme_certificate.md) | +| DELETE | `/nodes/{node}/certificates/custom` | [remove_custom_cert](endpoints/DELETE_nodes_node_certificates_custom.md) | +| POST | `/nodes/{node}/certificates/custom` | [upload_custom_cert](endpoints/POST_nodes_node_certificates_custom.md) | +| GET | `/nodes/{node}/certificates/info` | [info](endpoints/GET_nodes_node_certificates_info.md) | +| GET | `/nodes/{node}/config` | [get_config](endpoints/GET_nodes_node_config.md) | +| PUT | `/nodes/{node}/config` | [set_options](endpoints/PUT_nodes_node_config.md) | +| GET | `/nodes/{node}/disks` | [index](endpoints/GET_nodes_node_disks.md) | +| GET | `/nodes/{node}/disks/directory` | [index](endpoints/GET_nodes_node_disks_directory.md) | +| POST | `/nodes/{node}/disks/directory` | [create](endpoints/POST_nodes_node_disks_directory.md) | +| DELETE | `/nodes/{node}/disks/directory/{name}` | [delete](endpoints/DELETE_nodes_node_disks_directory_name.md) | +| POST | `/nodes/{node}/disks/initgpt` | [initgpt](endpoints/POST_nodes_node_disks_initgpt.md) | +| GET | `/nodes/{node}/disks/list` | [list](endpoints/GET_nodes_node_disks_list.md) | +| GET | `/nodes/{node}/disks/lvm` | [index](endpoints/GET_nodes_node_disks_lvm.md) | +| POST | `/nodes/{node}/disks/lvm` | [create](endpoints/POST_nodes_node_disks_lvm.md) | +| DELETE | `/nodes/{node}/disks/lvm/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvm_name.md) | +| GET | `/nodes/{node}/disks/lvmthin` | [index](endpoints/GET_nodes_node_disks_lvmthin.md) | +| POST | `/nodes/{node}/disks/lvmthin` | [create](endpoints/POST_nodes_node_disks_lvmthin.md) | +| DELETE | `/nodes/{node}/disks/lvmthin/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvmthin_name.md) | +| GET | `/nodes/{node}/disks/smart` | [smart](endpoints/GET_nodes_node_disks_smart.md) | +| PUT | `/nodes/{node}/disks/wipedisk` | [wipe_disk](endpoints/PUT_nodes_node_disks_wipedisk.md) | +| GET | `/nodes/{node}/disks/zfs` | [index](endpoints/GET_nodes_node_disks_zfs.md) | +| POST | `/nodes/{node}/disks/zfs` | [create](endpoints/POST_nodes_node_disks_zfs.md) | +| DELETE | `/nodes/{node}/disks/zfs/{name}` | [delete](endpoints/DELETE_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/disks/zfs/{name}` | [detail](endpoints/GET_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/dns` | [dns](endpoints/GET_nodes_node_dns.md) | +| PUT | `/nodes/{node}/dns` | [update_dns](endpoints/PUT_nodes_node_dns.md) | +| POST | `/nodes/{node}/execute` | [execute](endpoints/POST_nodes_node_execute.md) | +| GET | `/nodes/{node}/firewall` | [index](endpoints/GET_nodes_node_firewall.md) | +| GET | `/nodes/{node}/firewall/log` | [log](endpoints/GET_nodes_node_firewall_log.md) | +| GET | `/nodes/{node}/firewall/options` | [get_options](endpoints/GET_nodes_node_firewall_options.md) | +| PUT | `/nodes/{node}/firewall/options` | [set_options](endpoints/PUT_nodes_node_firewall_options.md) | +| GET | `/nodes/{node}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_firewall_rules.md) | +| POST | `/nodes/{node}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_firewall_rules.md) | +| DELETE | `/nodes/{node}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/hardware` | [index](endpoints/GET_nodes_node_hardware.md) | +| GET | `/nodes/{node}/hardware/pci` | [pci_scan](endpoints/GET_nodes_node_hardware_pci.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}` | [pci_index](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev` | [mdevscan](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping_mdev.md) | +| GET | `/nodes/{node}/hardware/usb` | [usbscan](endpoints/GET_nodes_node_hardware_usb.md) | +| GET | `/nodes/{node}/hosts` | [get_etc_hosts](endpoints/GET_nodes_node_hosts.md) | +| POST | `/nodes/{node}/hosts` | [write_etc_hosts](endpoints/POST_nodes_node_hosts.md) | +| GET | `/nodes/{node}/journal` | [journal](endpoints/GET_nodes_node_journal.md) | +| GET | `/nodes/{node}/lxc` | [vmlist](endpoints/GET_nodes_node_lxc.md) | +| POST | `/nodes/{node}/lxc` | [create_vm](endpoints/POST_nodes_node_lxc.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_lxc_vmid.md) | +| GET | `/nodes/{node}/lxc/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_lxc_vmid.md) | +| POST | `/nodes/{node}/lxc/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_lxc_vmid_clone.md) | +| GET | `/nodes/{node}/lxc/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_lxc_vmid_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_lxc_vmid_config.md) | +| GET | `/nodes/{node}/lxc/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_lxc_vmid_feature.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall` | [index](endpoints/GET_nodes_node_lxc_vmid_firewall.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_lxc_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_lxc_vmid_firewall_log.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_lxc_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_lxc_vmid_firewall_options.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_lxc_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_lxc_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_lxc_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/interfaces` | [ip](endpoints/GET_nodes_node_lxc_vmid_interfaces.md) | +| GET | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/move_volume` | [move_volume](endpoints/POST_nodes_node_lxc_vmid_move_volume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_lxc_vmid_mtunnel.md) | +| GET | `/nodes/{node}/lxc/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_lxc_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/lxc/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_lxc_vmid_pending.md) | +| POST | `/nodes/{node}/lxc/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_lxc_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_lxc_vmid_resize.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_lxc_vmid_rrd.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_lxc_vmid_rrddata.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot` | [list](endpoints/GET_nodes_node_lxc_vmid_snapshot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_lxc_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_lxc_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/lxc/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_lxc_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_lxc_vmid_status.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_lxc_vmid_status_current.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_lxc_vmid_status_reboot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_lxc_vmid_status_resume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_lxc_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_lxc_vmid_status_start.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_lxc_vmid_status_stop.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_lxc_vmid_status_suspend.md) | +| POST | `/nodes/{node}/lxc/{vmid}/template` | [template](endpoints/POST_nodes_node_lxc_vmid_template.md) | +| POST | `/nodes/{node}/lxc/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_lxc_vmid_termproxy.md) | +| POST | `/nodes/{node}/lxc/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_lxc_vmid_vncproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_lxc_vmid_vncwebsocket.md) | +| POST | `/nodes/{node}/migrateall` | [migrateall](endpoints/POST_nodes_node_migrateall.md) | +| GET | `/nodes/{node}/netstat` | [netstat](endpoints/GET_nodes_node_netstat.md) | +| DELETE | `/nodes/{node}/network` | [revert_network_changes](endpoints/DELETE_nodes_node_network.md) | +| GET | `/nodes/{node}/network` | [index](endpoints/GET_nodes_node_network.md) | +| POST | `/nodes/{node}/network` | [create_network](endpoints/POST_nodes_node_network.md) | +| PUT | `/nodes/{node}/network` | [reload_network_config](endpoints/PUT_nodes_node_network.md) | +| DELETE | `/nodes/{node}/network/{iface}` | [delete_network](endpoints/DELETE_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/network/{iface}` | [network_config](endpoints/GET_nodes_node_network_iface.md) | +| PUT | `/nodes/{node}/network/{iface}` | [update_network](endpoints/PUT_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/qemu` | [vmlist](endpoints/GET_nodes_node_qemu.md) | +| POST | `/nodes/{node}/qemu` | [create_vm](endpoints/POST_nodes_node_qemu.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent` | [index](endpoints/GET_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent` | [agent](endpoints/POST_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/exec` | [exec](endpoints/POST_nodes_node_qemu_vmid_agent_exec.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/exec-status` | [exec-status](endpoints/GET_nodes_node_qemu_vmid_agent_exec_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/file-read` | [file-read](endpoints/GET_nodes_node_qemu_vmid_agent_file_read.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/file-write` | [file-write](endpoints/POST_nodes_node_qemu_vmid_agent_file_write.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze` | [fsfreeze-freeze](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_freeze.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status` | [fsfreeze-status](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_status.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw` | [fsfreeze-thaw](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_thaw.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fstrim` | [fstrim](endpoints/POST_nodes_node_qemu_vmid_agent_fstrim.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-fsinfo` | [get-fsinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_fsinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-host-name` | [get-host-name](endpoints/GET_nodes_node_qemu_vmid_agent_get_host_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info` | [get-memory-block-info](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_block_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks` | [get-memory-blocks](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_blocks.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-osinfo` | [get-osinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_osinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-time` | [get-time](endpoints/GET_nodes_node_qemu_vmid_agent_get_time.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-timezone` | [get-timezone](endpoints/GET_nodes_node_qemu_vmid_agent_get_timezone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-users` | [get-users](endpoints/GET_nodes_node_qemu_vmid_agent_get_users.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-vcpus` | [get-vcpus](endpoints/GET_nodes_node_qemu_vmid_agent_get_vcpus.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/info` | [info](endpoints/GET_nodes_node_qemu_vmid_agent_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces` | [network-get-interfaces](endpoints/GET_nodes_node_qemu_vmid_agent_network_get_interfaces.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/ping` | [ping](endpoints/POST_nodes_node_qemu_vmid_agent_ping.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/set-user-password` | [set-user-password](endpoints/POST_nodes_node_qemu_vmid_agent_set_user_password.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/shutdown` | [shutdown](endpoints/POST_nodes_node_qemu_vmid_agent_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-disk` | [suspend-disk](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid` | [suspend-hybrid](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_hybrid.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-ram` | [suspend-ram](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_ram.md) | +| POST | `/nodes/{node}/qemu/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_qemu_vmid_clone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_pending](endpoints/GET_nodes_node_qemu_vmid_cloudinit.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_update](endpoints/PUT_nodes_node_qemu_vmid_cloudinit.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit/dump` | [cloudinit_generated_config_dump](endpoints/GET_nodes_node_qemu_vmid_cloudinit_dump.md) | +| GET | `/nodes/{node}/qemu/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/config` | [update_vm_async](endpoints/POST_nodes_node_qemu_vmid_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/dbus-vmstate` | [dbus_vmstate](endpoints/POST_nodes_node_qemu_vmid_dbus_vmstate.md) | +| GET | `/nodes/{node}/qemu/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_qemu_vmid_feature.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall` | [index](endpoints/GET_nodes_node_qemu_vmid_firewall.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_qemu_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_qemu_vmid_firewall_log.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_qemu_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_qemu_vmid_firewall_options.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_qemu_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_qemu_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_qemu_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/monitor` | [monitor](endpoints/POST_nodes_node_qemu_vmid_monitor.md) | +| POST | `/nodes/{node}/qemu/{vmid}/move_disk` | [move_vm_disk](endpoints/POST_nodes_node_qemu_vmid_move_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_qemu_vmid_mtunnel.md) | +| GET | `/nodes/{node}/qemu/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_qemu_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/qemu/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_qemu_vmid_pending.md) | +| POST | `/nodes/{node}/qemu/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_qemu_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_qemu_vmid_resize.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_qemu_vmid_rrd.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_qemu_vmid_rrddata.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/sendkey` | [vm_sendkey](endpoints/PUT_nodes_node_qemu_vmid_sendkey.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot_list](endpoints/GET_nodes_node_qemu_vmid_snapshot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_qemu_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_qemu_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/qemu/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_qemu_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_qemu_vmid_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_qemu_vmid_status_current.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_qemu_vmid_status_reboot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reset` | [vm_reset](endpoints/POST_nodes_node_qemu_vmid_status_reset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_qemu_vmid_status_resume.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_qemu_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_qemu_vmid_status_start.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_qemu_vmid_status_stop.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_qemu_vmid_status_suspend.md) | +| POST | `/nodes/{node}/qemu/{vmid}/template` | [template](endpoints/POST_nodes_node_qemu_vmid_template.md) | +| POST | `/nodes/{node}/qemu/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_qemu_vmid_termproxy.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/unlink` | [unlink](endpoints/PUT_nodes_node_qemu_vmid_unlink.md) | +| POST | `/nodes/{node}/qemu/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_qemu_vmid_vncproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_qemu_vmid_vncwebsocket.md) | +| GET | `/nodes/{node}/query-oci-repo-tags` | [query_oci_repo_tags](endpoints/GET_nodes_node_query_oci_repo_tags.md) | +| GET | `/nodes/{node}/query-url-metadata` | [query_url_metadata](endpoints/GET_nodes_node_query_url_metadata.md) | +| GET | `/nodes/{node}/replication` | [status](endpoints/GET_nodes_node_replication.md) | +| GET | `/nodes/{node}/replication/{id}` | [index](endpoints/GET_nodes_node_replication_id.md) | +| GET | `/nodes/{node}/replication/{id}/log` | [read_job_log](endpoints/GET_nodes_node_replication_id_log.md) | +| POST | `/nodes/{node}/replication/{id}/schedule_now` | [schedule_now](endpoints/POST_nodes_node_replication_id_schedule_now.md) | +| GET | `/nodes/{node}/replication/{id}/status` | [job_status](endpoints/GET_nodes_node_replication_id_status.md) | +| GET | `/nodes/{node}/report` | [report](endpoints/GET_nodes_node_report.md) | +| GET | `/nodes/{node}/rrd` | [rrd](endpoints/GET_nodes_node_rrd.md) | +| GET | `/nodes/{node}/rrddata` | [rrddata](endpoints/GET_nodes_node_rrddata.md) | +| GET | `/nodes/{node}/scan` | [index](endpoints/GET_nodes_node_scan.md) | +| GET | `/nodes/{node}/scan/cifs` | [cifsscan](endpoints/GET_nodes_node_scan_cifs.md) | +| GET | `/nodes/{node}/scan/iscsi` | [iscsiscan](endpoints/GET_nodes_node_scan_iscsi.md) | +| GET | `/nodes/{node}/scan/lvm` | [lvmscan](endpoints/GET_nodes_node_scan_lvm.md) | +| GET | `/nodes/{node}/scan/lvmthin` | [lvmthinscan](endpoints/GET_nodes_node_scan_lvmthin.md) | +| GET | `/nodes/{node}/scan/nfs` | [nfsscan](endpoints/GET_nodes_node_scan_nfs.md) | +| GET | `/nodes/{node}/scan/pbs` | [pbsscan](endpoints/GET_nodes_node_scan_pbs.md) | +| GET | `/nodes/{node}/scan/zfs` | [zfsscan](endpoints/GET_nodes_node_scan_zfs.md) | +| GET | `/nodes/{node}/sdn` | [sdnindex](endpoints/GET_nodes_node_sdn.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}` | [diridx](endpoints/GET_nodes_node_sdn_fabrics_fabric.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/interfaces` | [interfaces](endpoints/GET_nodes_node_sdn_fabrics_fabric_interfaces.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/neighbors` | [neighbors](endpoints/GET_nodes_node_sdn_fabrics_fabric_neighbors.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/routes` | [routes](endpoints/GET_nodes_node_sdn_fabrics_fabric_routes.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}` | [diridx](endpoints/GET_nodes_node_sdn_vnets_vnet.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}/mac-vrf` | [mac-vrf](endpoints/GET_nodes_node_sdn_vnets_vnet_mac_vrf.md) | +| GET | `/nodes/{node}/sdn/zones` | [index](endpoints/GET_nodes_node_sdn_zones.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}` | [diridx](endpoints/GET_nodes_node_sdn_zones_zone.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/bridges` | [bridges](endpoints/GET_nodes_node_sdn_zones_zone_bridges.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/content` | [index](endpoints/GET_nodes_node_sdn_zones_zone_content.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/ip-vrf` | [ip-vrf](endpoints/GET_nodes_node_sdn_zones_zone_ip_vrf.md) | +| GET | `/nodes/{node}/services` | [index](endpoints/GET_nodes_node_services.md) | +| GET | `/nodes/{node}/services/{service}` | [srvcmdidx](endpoints/GET_nodes_node_services_service.md) | +| POST | `/nodes/{node}/services/{service}/reload` | [service_reload](endpoints/POST_nodes_node_services_service_reload.md) | +| POST | `/nodes/{node}/services/{service}/restart` | [service_restart](endpoints/POST_nodes_node_services_service_restart.md) | +| POST | `/nodes/{node}/services/{service}/start` | [service_start](endpoints/POST_nodes_node_services_service_start.md) | +| GET | `/nodes/{node}/services/{service}/state` | [service_state](endpoints/GET_nodes_node_services_service_state.md) | +| POST | `/nodes/{node}/services/{service}/stop` | [service_stop](endpoints/POST_nodes_node_services_service_stop.md) | +| POST | `/nodes/{node}/spiceshell` | [spiceshell](endpoints/POST_nodes_node_spiceshell.md) | +| POST | `/nodes/{node}/startall` | [startall](endpoints/POST_nodes_node_startall.md) | +| GET | `/nodes/{node}/status` | [status](endpoints/GET_nodes_node_status.md) | +| POST | `/nodes/{node}/status` | [node_cmd](endpoints/POST_nodes_node_status.md) | +| POST | `/nodes/{node}/stopall` | [stopall](endpoints/POST_nodes_node_stopall.md) | +| GET | `/nodes/{node}/storage` | [index](endpoints/GET_nodes_node_storage.md) | +| GET | `/nodes/{node}/storage/{storage}` | [diridx](endpoints/GET_nodes_node_storage_storage.md) | +| GET | `/nodes/{node}/storage/{storage}/content` | [index](endpoints/GET_nodes_node_storage_storage_content.md) | +| POST | `/nodes/{node}/storage/{storage}/content` | [create](endpoints/POST_nodes_node_storage_storage_content.md) | +| DELETE | `/nodes/{node}/storage/{storage}/content/{volume}` | [delete](endpoints/DELETE_nodes_node_storage_storage_content_volume.md) | +| GET | `/nodes/{node}/storage/{storage}/content/{volume}` | [info](endpoints/GET_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/content/{volume}` | [copy](endpoints/POST_nodes_node_storage_storage_content_volume.md) | +| PUT | `/nodes/{node}/storage/{storage}/content/{volume}` | [updateattributes](endpoints/PUT_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/download-url` | [download_url](endpoints/POST_nodes_node_storage_storage_download_url.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/download` | [download](endpoints/GET_nodes_node_storage_storage_file_restore_download.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/list` | [list](endpoints/GET_nodes_node_storage_storage_file_restore_list.md) | +| GET | `/nodes/{node}/storage/{storage}/identity` | [identity](endpoints/GET_nodes_node_storage_storage_identity.md) | +| GET | `/nodes/{node}/storage/{storage}/import-metadata` | [get_import_metadata](endpoints/GET_nodes_node_storage_storage_import_metadata.md) | +| POST | `/nodes/{node}/storage/{storage}/oci-registry-pull` | [oci_registry_pull](endpoints/POST_nodes_node_storage_storage_oci_registry_pull.md) | +| DELETE | `/nodes/{node}/storage/{storage}/prunebackups` | [delete](endpoints/DELETE_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/prunebackups` | [dryrun](endpoints/GET_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/rrd` | [rrd](endpoints/GET_nodes_node_storage_storage_rrd.md) | +| GET | `/nodes/{node}/storage/{storage}/rrddata` | [rrddata](endpoints/GET_nodes_node_storage_storage_rrddata.md) | +| GET | `/nodes/{node}/storage/{storage}/status` | [read_status](endpoints/GET_nodes_node_storage_storage_status.md) | +| POST | `/nodes/{node}/storage/{storage}/upload` | [upload](endpoints/POST_nodes_node_storage_storage_upload.md) | +| DELETE | `/nodes/{node}/subscription` | [delete](endpoints/DELETE_nodes_node_subscription.md) | +| GET | `/nodes/{node}/subscription` | [get](endpoints/GET_nodes_node_subscription.md) | +| POST | `/nodes/{node}/subscription` | [update](endpoints/POST_nodes_node_subscription.md) | +| PUT | `/nodes/{node}/subscription` | [set](endpoints/PUT_nodes_node_subscription.md) | +| POST | `/nodes/{node}/suspendall` | [suspendall](endpoints/POST_nodes_node_suspendall.md) | +| GET | `/nodes/{node}/syslog` | [syslog](endpoints/GET_nodes_node_syslog.md) | +| GET | `/nodes/{node}/tasks` | [node_tasks](endpoints/GET_nodes_node_tasks.md) | +| DELETE | `/nodes/{node}/tasks/{upid}` | [stop_task](endpoints/DELETE_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}` | [upid_index](endpoints/GET_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}/log` | [read_task_log](endpoints/GET_nodes_node_tasks_upid_log.md) | +| GET | `/nodes/{node}/tasks/{upid}/status` | [read_task_status](endpoints/GET_nodes_node_tasks_upid_status.md) | +| POST | `/nodes/{node}/termproxy` | [termproxy](endpoints/POST_nodes_node_termproxy.md) | +| GET | `/nodes/{node}/time` | [time](endpoints/GET_nodes_node_time.md) | +| PUT | `/nodes/{node}/time` | [set_timezone](endpoints/PUT_nodes_node_time.md) | +| GET | `/nodes/{node}/version` | [version](endpoints/GET_nodes_node_version.md) | +| POST | `/nodes/{node}/vncshell` | [vncshell](endpoints/POST_nodes_node_vncshell.md) | +| GET | `/nodes/{node}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_vncwebsocket.md) | +| POST | `/nodes/{node}/vzdump` | [vzdump](endpoints/POST_nodes_node_vzdump.md) | +| GET | `/nodes/{node}/vzdump/defaults` | [defaults](endpoints/GET_nodes_node_vzdump_defaults.md) | +| GET | `/nodes/{node}/vzdump/extractconfig` | [extractconfig](endpoints/GET_nodes_node_vzdump_extractconfig.md) | +| POST | `/nodes/{node}/wakeonlan` | [wakeonlan](endpoints/POST_nodes_node_wakeonlan.md) | +| DELETE | `/pools` | [delete_pool](endpoints/DELETE_pools.md) | +| GET | `/pools` | [index](endpoints/GET_pools.md) | +| POST | `/pools` | [create_pool](endpoints/POST_pools.md) | +| PUT | `/pools` | [update_pool](endpoints/PUT_pools.md) | +| DELETE | `/pools/{poolid}` | [delete_pool_deprecated](endpoints/DELETE_pools_poolid.md) | +| GET | `/pools/{poolid}` | [read_pool](endpoints/GET_pools_poolid.md) | +| PUT | `/pools/{poolid}` | [update_pool_deprecated](endpoints/PUT_pools_poolid.md) | +| GET | `/storage` | [index](endpoints/GET_storage.md) | +| POST | `/storage` | [create](endpoints/POST_storage.md) | +| DELETE | `/storage/{storage}` | [delete](endpoints/DELETE_storage_storage.md) | +| GET | `/storage/{storage}` | [read](endpoints/GET_storage_storage.md) | +| PUT | `/storage/{storage}` | [update](endpoints/PUT_storage_storage.md) | +| GET | `/version` | [version](endpoints/GET_version.md) | diff --git a/docs/pve-api/markdown/nodes.md b/docs/pve-api/markdown/nodes.md new file mode 100644 index 00000000000..4bef8017eaa --- /dev/null +++ b/docs/pve-api/markdown/nodes.md @@ -0,0 +1,364 @@ +# /nodes + +Endpoints in the `/nodes` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/nodes` | [index](endpoints/GET_nodes.md) | +| GET | `/nodes/{node}` | [index](endpoints/GET_nodes_node.md) | +| GET | `/nodes/{node}/aplinfo` | [aplinfo](endpoints/GET_nodes_node_aplinfo.md) | +| POST | `/nodes/{node}/aplinfo` | [apl_download](endpoints/POST_nodes_node_aplinfo.md) | +| GET | `/nodes/{node}/apt` | [index](endpoints/GET_nodes_node_apt.md) | +| GET | `/nodes/{node}/apt/changelog` | [changelog](endpoints/GET_nodes_node_apt_changelog.md) | +| GET | `/nodes/{node}/apt/repositories` | [repositories](endpoints/GET_nodes_node_apt_repositories.md) | +| POST | `/nodes/{node}/apt/repositories` | [change_repository](endpoints/POST_nodes_node_apt_repositories.md) | +| PUT | `/nodes/{node}/apt/repositories` | [add_repository](endpoints/PUT_nodes_node_apt_repositories.md) | +| GET | `/nodes/{node}/apt/update` | [list_updates](endpoints/GET_nodes_node_apt_update.md) | +| POST | `/nodes/{node}/apt/update` | [update_database](endpoints/POST_nodes_node_apt_update.md) | +| GET | `/nodes/{node}/apt/versions` | [versions](endpoints/GET_nodes_node_apt_versions.md) | +| GET | `/nodes/{node}/capabilities` | [index](endpoints/GET_nodes_node_capabilities.md) | +| GET | `/nodes/{node}/capabilities/qemu` | [qemu_caps_index](endpoints/GET_nodes_node_capabilities_qemu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu.md) | +| GET | `/nodes/{node}/capabilities/qemu/cpu-flags` | [index](endpoints/GET_nodes_node_capabilities_qemu_cpu_flags.md) | +| GET | `/nodes/{node}/capabilities/qemu/machines` | [types](endpoints/GET_nodes_node_capabilities_qemu_machines.md) | +| GET | `/nodes/{node}/capabilities/qemu/migration` | [capabilities](endpoints/GET_nodes_node_capabilities_qemu_migration.md) | +| GET | `/nodes/{node}/ceph` | [index](endpoints/GET_nodes_node_ceph.md) | +| GET | `/nodes/{node}/ceph/cfg` | [index](endpoints/GET_nodes_node_ceph_cfg.md) | +| GET | `/nodes/{node}/ceph/cfg/db` | [db](endpoints/GET_nodes_node_ceph_cfg_db.md) | +| GET | `/nodes/{node}/ceph/cfg/raw` | [raw](endpoints/GET_nodes_node_ceph_cfg_raw.md) | +| GET | `/nodes/{node}/ceph/cfg/value` | [value](endpoints/GET_nodes_node_ceph_cfg_value.md) | +| GET | `/nodes/{node}/ceph/cmd-safety` | [cmd_safety](endpoints/GET_nodes_node_ceph_cmd_safety.md) | +| GET | `/nodes/{node}/ceph/crush` | [crush](endpoints/GET_nodes_node_ceph_crush.md) | +| GET | `/nodes/{node}/ceph/fs` | [index](endpoints/GET_nodes_node_ceph_fs.md) | +| DELETE | `/nodes/{node}/ceph/fs/{name}` | [destroyfs](endpoints/DELETE_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/fs/{name}` | [createfs](endpoints/POST_nodes_node_ceph_fs_name.md) | +| POST | `/nodes/{node}/ceph/init` | [init](endpoints/POST_nodes_node_ceph_init.md) | +| GET | `/nodes/{node}/ceph/log` | [log](endpoints/GET_nodes_node_ceph_log.md) | +| GET | `/nodes/{node}/ceph/mds` | [index](endpoints/GET_nodes_node_ceph_mds.md) | +| DELETE | `/nodes/{node}/ceph/mds/{name}` | [destroymds](endpoints/DELETE_nodes_node_ceph_mds_name.md) | +| POST | `/nodes/{node}/ceph/mds/{name}` | [createmds](endpoints/POST_nodes_node_ceph_mds_name.md) | +| GET | `/nodes/{node}/ceph/mgr` | [index](endpoints/GET_nodes_node_ceph_mgr.md) | +| DELETE | `/nodes/{node}/ceph/mgr/{id}` | [destroymgr](endpoints/DELETE_nodes_node_ceph_mgr_id.md) | +| POST | `/nodes/{node}/ceph/mgr/{id}` | [createmgr](endpoints/POST_nodes_node_ceph_mgr_id.md) | +| GET | `/nodes/{node}/ceph/mon` | [listmon](endpoints/GET_nodes_node_ceph_mon.md) | +| DELETE | `/nodes/{node}/ceph/mon/{monid}` | [destroymon](endpoints/DELETE_nodes_node_ceph_mon_monid.md) | +| POST | `/nodes/{node}/ceph/mon/{monid}` | [createmon](endpoints/POST_nodes_node_ceph_mon_monid.md) | +| GET | `/nodes/{node}/ceph/osd` | [index](endpoints/GET_nodes_node_ceph_osd.md) | +| POST | `/nodes/{node}/ceph/osd` | [createosd](endpoints/POST_nodes_node_ceph_osd.md) | +| DELETE | `/nodes/{node}/ceph/osd/{osdid}` | [destroyosd](endpoints/DELETE_nodes_node_ceph_osd_osdid.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}` | [osdindex](endpoints/GET_nodes_node_ceph_osd_osdid.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/in` | [in](endpoints/POST_nodes_node_ceph_osd_osdid_in.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/lv-info` | [osdvolume](endpoints/GET_nodes_node_ceph_osd_osdid_lv_info.md) | +| GET | `/nodes/{node}/ceph/osd/{osdid}/metadata` | [osddetails](endpoints/GET_nodes_node_ceph_osd_osdid_metadata.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/out` | [out](endpoints/POST_nodes_node_ceph_osd_osdid_out.md) | +| POST | `/nodes/{node}/ceph/osd/{osdid}/scrub` | [scrub](endpoints/POST_nodes_node_ceph_osd_osdid_scrub.md) | +| GET | `/nodes/{node}/ceph/pool` | [lspools](endpoints/GET_nodes_node_ceph_pool.md) | +| POST | `/nodes/{node}/ceph/pool` | [createpool](endpoints/POST_nodes_node_ceph_pool.md) | +| DELETE | `/nodes/{node}/ceph/pool/{name}` | [destroypool](endpoints/DELETE_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}` | [poolindex](endpoints/GET_nodes_node_ceph_pool_name.md) | +| PUT | `/nodes/{node}/ceph/pool/{name}` | [setpool](endpoints/PUT_nodes_node_ceph_pool_name.md) | +| GET | `/nodes/{node}/ceph/pool/{name}/status` | [getpool](endpoints/GET_nodes_node_ceph_pool_name_status.md) | +| POST | `/nodes/{node}/ceph/restart` | [restart](endpoints/POST_nodes_node_ceph_restart.md) | +| GET | `/nodes/{node}/ceph/rules` | [rules](endpoints/GET_nodes_node_ceph_rules.md) | +| POST | `/nodes/{node}/ceph/start` | [start](endpoints/POST_nodes_node_ceph_start.md) | +| GET | `/nodes/{node}/ceph/status` | [status](endpoints/GET_nodes_node_ceph_status.md) | +| POST | `/nodes/{node}/ceph/stop` | [stop](endpoints/POST_nodes_node_ceph_stop.md) | +| GET | `/nodes/{node}/certificates` | [index](endpoints/GET_nodes_node_certificates.md) | +| GET | `/nodes/{node}/certificates/acme` | [index](endpoints/GET_nodes_node_certificates_acme.md) | +| DELETE | `/nodes/{node}/certificates/acme/certificate` | [revoke_certificate](endpoints/DELETE_nodes_node_certificates_acme_certificate.md) | +| POST | `/nodes/{node}/certificates/acme/certificate` | [new_certificate](endpoints/POST_nodes_node_certificates_acme_certificate.md) | +| PUT | `/nodes/{node}/certificates/acme/certificate` | [renew_certificate](endpoints/PUT_nodes_node_certificates_acme_certificate.md) | +| DELETE | `/nodes/{node}/certificates/custom` | [remove_custom_cert](endpoints/DELETE_nodes_node_certificates_custom.md) | +| POST | `/nodes/{node}/certificates/custom` | [upload_custom_cert](endpoints/POST_nodes_node_certificates_custom.md) | +| GET | `/nodes/{node}/certificates/info` | [info](endpoints/GET_nodes_node_certificates_info.md) | +| GET | `/nodes/{node}/config` | [get_config](endpoints/GET_nodes_node_config.md) | +| PUT | `/nodes/{node}/config` | [set_options](endpoints/PUT_nodes_node_config.md) | +| GET | `/nodes/{node}/disks` | [index](endpoints/GET_nodes_node_disks.md) | +| GET | `/nodes/{node}/disks/directory` | [index](endpoints/GET_nodes_node_disks_directory.md) | +| POST | `/nodes/{node}/disks/directory` | [create](endpoints/POST_nodes_node_disks_directory.md) | +| DELETE | `/nodes/{node}/disks/directory/{name}` | [delete](endpoints/DELETE_nodes_node_disks_directory_name.md) | +| POST | `/nodes/{node}/disks/initgpt` | [initgpt](endpoints/POST_nodes_node_disks_initgpt.md) | +| GET | `/nodes/{node}/disks/list` | [list](endpoints/GET_nodes_node_disks_list.md) | +| GET | `/nodes/{node}/disks/lvm` | [index](endpoints/GET_nodes_node_disks_lvm.md) | +| POST | `/nodes/{node}/disks/lvm` | [create](endpoints/POST_nodes_node_disks_lvm.md) | +| DELETE | `/nodes/{node}/disks/lvm/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvm_name.md) | +| GET | `/nodes/{node}/disks/lvmthin` | [index](endpoints/GET_nodes_node_disks_lvmthin.md) | +| POST | `/nodes/{node}/disks/lvmthin` | [create](endpoints/POST_nodes_node_disks_lvmthin.md) | +| DELETE | `/nodes/{node}/disks/lvmthin/{name}` | [delete](endpoints/DELETE_nodes_node_disks_lvmthin_name.md) | +| GET | `/nodes/{node}/disks/smart` | [smart](endpoints/GET_nodes_node_disks_smart.md) | +| PUT | `/nodes/{node}/disks/wipedisk` | [wipe_disk](endpoints/PUT_nodes_node_disks_wipedisk.md) | +| GET | `/nodes/{node}/disks/zfs` | [index](endpoints/GET_nodes_node_disks_zfs.md) | +| POST | `/nodes/{node}/disks/zfs` | [create](endpoints/POST_nodes_node_disks_zfs.md) | +| DELETE | `/nodes/{node}/disks/zfs/{name}` | [delete](endpoints/DELETE_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/disks/zfs/{name}` | [detail](endpoints/GET_nodes_node_disks_zfs_name.md) | +| GET | `/nodes/{node}/dns` | [dns](endpoints/GET_nodes_node_dns.md) | +| PUT | `/nodes/{node}/dns` | [update_dns](endpoints/PUT_nodes_node_dns.md) | +| POST | `/nodes/{node}/execute` | [execute](endpoints/POST_nodes_node_execute.md) | +| GET | `/nodes/{node}/firewall` | [index](endpoints/GET_nodes_node_firewall.md) | +| GET | `/nodes/{node}/firewall/log` | [log](endpoints/GET_nodes_node_firewall_log.md) | +| GET | `/nodes/{node}/firewall/options` | [get_options](endpoints/GET_nodes_node_firewall_options.md) | +| PUT | `/nodes/{node}/firewall/options` | [set_options](endpoints/PUT_nodes_node_firewall_options.md) | +| GET | `/nodes/{node}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_firewall_rules.md) | +| POST | `/nodes/{node}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_firewall_rules.md) | +| DELETE | `/nodes/{node}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_firewall_rules_pos.md) | +| GET | `/nodes/{node}/hardware` | [index](endpoints/GET_nodes_node_hardware.md) | +| GET | `/nodes/{node}/hardware/pci` | [pci_scan](endpoints/GET_nodes_node_hardware_pci.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}` | [pci_index](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping.md) | +| GET | `/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev` | [mdevscan](endpoints/GET_nodes_node_hardware_pci_pci_id_or_mapping_mdev.md) | +| GET | `/nodes/{node}/hardware/usb` | [usbscan](endpoints/GET_nodes_node_hardware_usb.md) | +| GET | `/nodes/{node}/hosts` | [get_etc_hosts](endpoints/GET_nodes_node_hosts.md) | +| POST | `/nodes/{node}/hosts` | [write_etc_hosts](endpoints/POST_nodes_node_hosts.md) | +| GET | `/nodes/{node}/journal` | [journal](endpoints/GET_nodes_node_journal.md) | +| GET | `/nodes/{node}/lxc` | [vmlist](endpoints/GET_nodes_node_lxc.md) | +| POST | `/nodes/{node}/lxc` | [create_vm](endpoints/POST_nodes_node_lxc.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_lxc_vmid.md) | +| GET | `/nodes/{node}/lxc/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_lxc_vmid.md) | +| POST | `/nodes/{node}/lxc/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_lxc_vmid_clone.md) | +| GET | `/nodes/{node}/lxc/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_lxc_vmid_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_lxc_vmid_config.md) | +| GET | `/nodes/{node}/lxc/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_lxc_vmid_feature.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall` | [index](endpoints/GET_nodes_node_lxc_vmid_firewall.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_lxc_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_lxc_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_lxc_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_lxc_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_lxc_vmid_firewall_log.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_lxc_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_lxc_vmid_firewall_options.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_lxc_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_lxc_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/lxc/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_lxc_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_lxc_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/lxc/{vmid}/interfaces` | [ip](endpoints/GET_nodes_node_lxc_vmid_interfaces.md) | +| GET | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_lxc_vmid_migrate.md) | +| POST | `/nodes/{node}/lxc/{vmid}/move_volume` | [move_volume](endpoints/POST_nodes_node_lxc_vmid_move_volume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_lxc_vmid_mtunnel.md) | +| GET | `/nodes/{node}/lxc/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_lxc_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/lxc/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_lxc_vmid_pending.md) | +| POST | `/nodes/{node}/lxc/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_lxc_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_lxc_vmid_resize.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_lxc_vmid_rrd.md) | +| GET | `/nodes/{node}/lxc/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_lxc_vmid_rrddata.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot` | [list](endpoints/GET_nodes_node_lxc_vmid_snapshot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_lxc_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_lxc_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_lxc_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/lxc/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_lxc_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_lxc_vmid_status.md) | +| GET | `/nodes/{node}/lxc/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_lxc_vmid_status_current.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_lxc_vmid_status_reboot.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_lxc_vmid_status_resume.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_lxc_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_lxc_vmid_status_start.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_lxc_vmid_status_stop.md) | +| POST | `/nodes/{node}/lxc/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_lxc_vmid_status_suspend.md) | +| POST | `/nodes/{node}/lxc/{vmid}/template` | [template](endpoints/POST_nodes_node_lxc_vmid_template.md) | +| POST | `/nodes/{node}/lxc/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_lxc_vmid_termproxy.md) | +| POST | `/nodes/{node}/lxc/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_lxc_vmid_vncproxy.md) | +| GET | `/nodes/{node}/lxc/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_lxc_vmid_vncwebsocket.md) | +| POST | `/nodes/{node}/migrateall` | [migrateall](endpoints/POST_nodes_node_migrateall.md) | +| GET | `/nodes/{node}/netstat` | [netstat](endpoints/GET_nodes_node_netstat.md) | +| DELETE | `/nodes/{node}/network` | [revert_network_changes](endpoints/DELETE_nodes_node_network.md) | +| GET | `/nodes/{node}/network` | [index](endpoints/GET_nodes_node_network.md) | +| POST | `/nodes/{node}/network` | [create_network](endpoints/POST_nodes_node_network.md) | +| PUT | `/nodes/{node}/network` | [reload_network_config](endpoints/PUT_nodes_node_network.md) | +| DELETE | `/nodes/{node}/network/{iface}` | [delete_network](endpoints/DELETE_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/network/{iface}` | [network_config](endpoints/GET_nodes_node_network_iface.md) | +| PUT | `/nodes/{node}/network/{iface}` | [update_network](endpoints/PUT_nodes_node_network_iface.md) | +| GET | `/nodes/{node}/qemu` | [vmlist](endpoints/GET_nodes_node_qemu.md) | +| POST | `/nodes/{node}/qemu` | [create_vm](endpoints/POST_nodes_node_qemu.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}` | [destroy_vm](endpoints/DELETE_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}` | [vmdiridx](endpoints/GET_nodes_node_qemu_vmid.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent` | [index](endpoints/GET_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent` | [agent](endpoints/POST_nodes_node_qemu_vmid_agent.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/exec` | [exec](endpoints/POST_nodes_node_qemu_vmid_agent_exec.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/exec-status` | [exec-status](endpoints/GET_nodes_node_qemu_vmid_agent_exec_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/file-read` | [file-read](endpoints/GET_nodes_node_qemu_vmid_agent_file_read.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/file-write` | [file-write](endpoints/POST_nodes_node_qemu_vmid_agent_file_write.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze` | [fsfreeze-freeze](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_freeze.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status` | [fsfreeze-status](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_status.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw` | [fsfreeze-thaw](endpoints/POST_nodes_node_qemu_vmid_agent_fsfreeze_thaw.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/fstrim` | [fstrim](endpoints/POST_nodes_node_qemu_vmid_agent_fstrim.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-fsinfo` | [get-fsinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_fsinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-host-name` | [get-host-name](endpoints/GET_nodes_node_qemu_vmid_agent_get_host_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info` | [get-memory-block-info](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_block_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks` | [get-memory-blocks](endpoints/GET_nodes_node_qemu_vmid_agent_get_memory_blocks.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-osinfo` | [get-osinfo](endpoints/GET_nodes_node_qemu_vmid_agent_get_osinfo.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-time` | [get-time](endpoints/GET_nodes_node_qemu_vmid_agent_get_time.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-timezone` | [get-timezone](endpoints/GET_nodes_node_qemu_vmid_agent_get_timezone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-users` | [get-users](endpoints/GET_nodes_node_qemu_vmid_agent_get_users.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/get-vcpus` | [get-vcpus](endpoints/GET_nodes_node_qemu_vmid_agent_get_vcpus.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/info` | [info](endpoints/GET_nodes_node_qemu_vmid_agent_info.md) | +| GET | `/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces` | [network-get-interfaces](endpoints/GET_nodes_node_qemu_vmid_agent_network_get_interfaces.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/ping` | [ping](endpoints/POST_nodes_node_qemu_vmid_agent_ping.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/set-user-password` | [set-user-password](endpoints/POST_nodes_node_qemu_vmid_agent_set_user_password.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/shutdown` | [shutdown](endpoints/POST_nodes_node_qemu_vmid_agent_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-disk` | [suspend-disk](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid` | [suspend-hybrid](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_hybrid.md) | +| POST | `/nodes/{node}/qemu/{vmid}/agent/suspend-ram` | [suspend-ram](endpoints/POST_nodes_node_qemu_vmid_agent_suspend_ram.md) | +| POST | `/nodes/{node}/qemu/{vmid}/clone` | [clone_vm](endpoints/POST_nodes_node_qemu_vmid_clone.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_pending](endpoints/GET_nodes_node_qemu_vmid_cloudinit.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/cloudinit` | [cloudinit_update](endpoints/PUT_nodes_node_qemu_vmid_cloudinit.md) | +| GET | `/nodes/{node}/qemu/{vmid}/cloudinit/dump` | [cloudinit_generated_config_dump](endpoints/GET_nodes_node_qemu_vmid_cloudinit_dump.md) | +| GET | `/nodes/{node}/qemu/{vmid}/config` | [vm_config](endpoints/GET_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/config` | [update_vm_async](endpoints/POST_nodes_node_qemu_vmid_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/config` | [update_vm](endpoints/PUT_nodes_node_qemu_vmid_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/dbus-vmstate` | [dbus_vmstate](endpoints/POST_nodes_node_qemu_vmid_dbus_vmstate.md) | +| GET | `/nodes/{node}/qemu/{vmid}/feature` | [vm_feature](endpoints/GET_nodes_node_qemu_vmid_feature.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall` | [index](endpoints/GET_nodes_node_qemu_vmid_firewall.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [get_aliases](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/aliases` | [create_alias](endpoints/POST_nodes_node_qemu_vmid_firewall_aliases.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [remove_alias](endpoints/DELETE_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [read_alias](endpoints/GET_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}` | [update_alias](endpoints/PUT_nodes_node_qemu_vmid_firewall_aliases_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [ipset_index](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset` | [create_ipset](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [delete_ipset](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [get_ipset](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}` | [create_ip](endpoints/POST_nodes_node_qemu_vmid_firewall_ipset_name.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [remove_ip](endpoints/DELETE_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [read_ip](endpoints/GET_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}` | [update_ip](endpoints/PUT_nodes_node_qemu_vmid_firewall_ipset_name_cidr.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/log` | [log](endpoints/GET_nodes_node_qemu_vmid_firewall_log.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/options` | [get_options](endpoints/GET_nodes_node_qemu_vmid_firewall_options.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/options` | [set_options](endpoints/PUT_nodes_node_qemu_vmid_firewall_options.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/refs` | [refs](endpoints/GET_nodes_node_qemu_vmid_firewall_refs.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [get_rules](endpoints/GET_nodes_node_qemu_vmid_firewall_rules.md) | +| POST | `/nodes/{node}/qemu/{vmid}/firewall/rules` | [create_rule](endpoints/POST_nodes_node_qemu_vmid_firewall_rules.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [delete_rule](endpoints/DELETE_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [get_rule](endpoints/GET_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}` | [update_rule](endpoints/PUT_nodes_node_qemu_vmid_firewall_rules_pos.md) | +| GET | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm_precondition](endpoints/GET_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/migrate` | [migrate_vm](endpoints/POST_nodes_node_qemu_vmid_migrate.md) | +| POST | `/nodes/{node}/qemu/{vmid}/monitor` | [monitor](endpoints/POST_nodes_node_qemu_vmid_monitor.md) | +| POST | `/nodes/{node}/qemu/{vmid}/move_disk` | [move_vm_disk](endpoints/POST_nodes_node_qemu_vmid_move_disk.md) | +| POST | `/nodes/{node}/qemu/{vmid}/mtunnel` | [mtunnel](endpoints/POST_nodes_node_qemu_vmid_mtunnel.md) | +| GET | `/nodes/{node}/qemu/{vmid}/mtunnelwebsocket` | [mtunnelwebsocket](endpoints/GET_nodes_node_qemu_vmid_mtunnelwebsocket.md) | +| GET | `/nodes/{node}/qemu/{vmid}/pending` | [vm_pending](endpoints/GET_nodes_node_qemu_vmid_pending.md) | +| POST | `/nodes/{node}/qemu/{vmid}/remote_migrate` | [remote_migrate_vm](endpoints/POST_nodes_node_qemu_vmid_remote_migrate.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/resize` | [resize_vm](endpoints/PUT_nodes_node_qemu_vmid_resize.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrd` | [rrd](endpoints/GET_nodes_node_qemu_vmid_rrd.md) | +| GET | `/nodes/{node}/qemu/{vmid}/rrddata` | [rrddata](endpoints/GET_nodes_node_qemu_vmid_rrddata.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/sendkey` | [vm_sendkey](endpoints/PUT_nodes_node_qemu_vmid_sendkey.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot_list](endpoints/GET_nodes_node_qemu_vmid_snapshot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot` | [snapshot](endpoints/POST_nodes_node_qemu_vmid_snapshot.md) | +| DELETE | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [delsnapshot](endpoints/DELETE_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}` | [snapshot_cmd_idx](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname.md) | +| GET | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [get_snapshot_config](endpoints/GET_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config` | [update_snapshot_config](endpoints/PUT_nodes_node_qemu_vmid_snapshot_snapname_config.md) | +| POST | `/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback` | [rollback](endpoints/POST_nodes_node_qemu_vmid_snapshot_snapname_rollback.md) | +| POST | `/nodes/{node}/qemu/{vmid}/spiceproxy` | [spiceproxy](endpoints/POST_nodes_node_qemu_vmid_spiceproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status` | [vmcmdidx](endpoints/GET_nodes_node_qemu_vmid_status.md) | +| GET | `/nodes/{node}/qemu/{vmid}/status/current` | [vm_status](endpoints/GET_nodes_node_qemu_vmid_status_current.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reboot` | [vm_reboot](endpoints/POST_nodes_node_qemu_vmid_status_reboot.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/reset` | [vm_reset](endpoints/POST_nodes_node_qemu_vmid_status_reset.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/resume` | [vm_resume](endpoints/POST_nodes_node_qemu_vmid_status_resume.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/shutdown` | [vm_shutdown](endpoints/POST_nodes_node_qemu_vmid_status_shutdown.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/start` | [vm_start](endpoints/POST_nodes_node_qemu_vmid_status_start.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/stop` | [vm_stop](endpoints/POST_nodes_node_qemu_vmid_status_stop.md) | +| POST | `/nodes/{node}/qemu/{vmid}/status/suspend` | [vm_suspend](endpoints/POST_nodes_node_qemu_vmid_status_suspend.md) | +| POST | `/nodes/{node}/qemu/{vmid}/template` | [template](endpoints/POST_nodes_node_qemu_vmid_template.md) | +| POST | `/nodes/{node}/qemu/{vmid}/termproxy` | [termproxy](endpoints/POST_nodes_node_qemu_vmid_termproxy.md) | +| PUT | `/nodes/{node}/qemu/{vmid}/unlink` | [unlink](endpoints/PUT_nodes_node_qemu_vmid_unlink.md) | +| POST | `/nodes/{node}/qemu/{vmid}/vncproxy` | [vncproxy](endpoints/POST_nodes_node_qemu_vmid_vncproxy.md) | +| GET | `/nodes/{node}/qemu/{vmid}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_qemu_vmid_vncwebsocket.md) | +| GET | `/nodes/{node}/query-oci-repo-tags` | [query_oci_repo_tags](endpoints/GET_nodes_node_query_oci_repo_tags.md) | +| GET | `/nodes/{node}/query-url-metadata` | [query_url_metadata](endpoints/GET_nodes_node_query_url_metadata.md) | +| GET | `/nodes/{node}/replication` | [status](endpoints/GET_nodes_node_replication.md) | +| GET | `/nodes/{node}/replication/{id}` | [index](endpoints/GET_nodes_node_replication_id.md) | +| GET | `/nodes/{node}/replication/{id}/log` | [read_job_log](endpoints/GET_nodes_node_replication_id_log.md) | +| POST | `/nodes/{node}/replication/{id}/schedule_now` | [schedule_now](endpoints/POST_nodes_node_replication_id_schedule_now.md) | +| GET | `/nodes/{node}/replication/{id}/status` | [job_status](endpoints/GET_nodes_node_replication_id_status.md) | +| GET | `/nodes/{node}/report` | [report](endpoints/GET_nodes_node_report.md) | +| GET | `/nodes/{node}/rrd` | [rrd](endpoints/GET_nodes_node_rrd.md) | +| GET | `/nodes/{node}/rrddata` | [rrddata](endpoints/GET_nodes_node_rrddata.md) | +| GET | `/nodes/{node}/scan` | [index](endpoints/GET_nodes_node_scan.md) | +| GET | `/nodes/{node}/scan/cifs` | [cifsscan](endpoints/GET_nodes_node_scan_cifs.md) | +| GET | `/nodes/{node}/scan/iscsi` | [iscsiscan](endpoints/GET_nodes_node_scan_iscsi.md) | +| GET | `/nodes/{node}/scan/lvm` | [lvmscan](endpoints/GET_nodes_node_scan_lvm.md) | +| GET | `/nodes/{node}/scan/lvmthin` | [lvmthinscan](endpoints/GET_nodes_node_scan_lvmthin.md) | +| GET | `/nodes/{node}/scan/nfs` | [nfsscan](endpoints/GET_nodes_node_scan_nfs.md) | +| GET | `/nodes/{node}/scan/pbs` | [pbsscan](endpoints/GET_nodes_node_scan_pbs.md) | +| GET | `/nodes/{node}/scan/zfs` | [zfsscan](endpoints/GET_nodes_node_scan_zfs.md) | +| GET | `/nodes/{node}/sdn` | [sdnindex](endpoints/GET_nodes_node_sdn.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}` | [diridx](endpoints/GET_nodes_node_sdn_fabrics_fabric.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/interfaces` | [interfaces](endpoints/GET_nodes_node_sdn_fabrics_fabric_interfaces.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/neighbors` | [neighbors](endpoints/GET_nodes_node_sdn_fabrics_fabric_neighbors.md) | +| GET | `/nodes/{node}/sdn/fabrics/{fabric}/routes` | [routes](endpoints/GET_nodes_node_sdn_fabrics_fabric_routes.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}` | [diridx](endpoints/GET_nodes_node_sdn_vnets_vnet.md) | +| GET | `/nodes/{node}/sdn/vnets/{vnet}/mac-vrf` | [mac-vrf](endpoints/GET_nodes_node_sdn_vnets_vnet_mac_vrf.md) | +| GET | `/nodes/{node}/sdn/zones` | [index](endpoints/GET_nodes_node_sdn_zones.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}` | [diridx](endpoints/GET_nodes_node_sdn_zones_zone.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/bridges` | [bridges](endpoints/GET_nodes_node_sdn_zones_zone_bridges.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/content` | [index](endpoints/GET_nodes_node_sdn_zones_zone_content.md) | +| GET | `/nodes/{node}/sdn/zones/{zone}/ip-vrf` | [ip-vrf](endpoints/GET_nodes_node_sdn_zones_zone_ip_vrf.md) | +| GET | `/nodes/{node}/services` | [index](endpoints/GET_nodes_node_services.md) | +| GET | `/nodes/{node}/services/{service}` | [srvcmdidx](endpoints/GET_nodes_node_services_service.md) | +| POST | `/nodes/{node}/services/{service}/reload` | [service_reload](endpoints/POST_nodes_node_services_service_reload.md) | +| POST | `/nodes/{node}/services/{service}/restart` | [service_restart](endpoints/POST_nodes_node_services_service_restart.md) | +| POST | `/nodes/{node}/services/{service}/start` | [service_start](endpoints/POST_nodes_node_services_service_start.md) | +| GET | `/nodes/{node}/services/{service}/state` | [service_state](endpoints/GET_nodes_node_services_service_state.md) | +| POST | `/nodes/{node}/services/{service}/stop` | [service_stop](endpoints/POST_nodes_node_services_service_stop.md) | +| POST | `/nodes/{node}/spiceshell` | [spiceshell](endpoints/POST_nodes_node_spiceshell.md) | +| POST | `/nodes/{node}/startall` | [startall](endpoints/POST_nodes_node_startall.md) | +| GET | `/nodes/{node}/status` | [status](endpoints/GET_nodes_node_status.md) | +| POST | `/nodes/{node}/status` | [node_cmd](endpoints/POST_nodes_node_status.md) | +| POST | `/nodes/{node}/stopall` | [stopall](endpoints/POST_nodes_node_stopall.md) | +| GET | `/nodes/{node}/storage` | [index](endpoints/GET_nodes_node_storage.md) | +| GET | `/nodes/{node}/storage/{storage}` | [diridx](endpoints/GET_nodes_node_storage_storage.md) | +| GET | `/nodes/{node}/storage/{storage}/content` | [index](endpoints/GET_nodes_node_storage_storage_content.md) | +| POST | `/nodes/{node}/storage/{storage}/content` | [create](endpoints/POST_nodes_node_storage_storage_content.md) | +| DELETE | `/nodes/{node}/storage/{storage}/content/{volume}` | [delete](endpoints/DELETE_nodes_node_storage_storage_content_volume.md) | +| GET | `/nodes/{node}/storage/{storage}/content/{volume}` | [info](endpoints/GET_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/content/{volume}` | [copy](endpoints/POST_nodes_node_storage_storage_content_volume.md) | +| PUT | `/nodes/{node}/storage/{storage}/content/{volume}` | [updateattributes](endpoints/PUT_nodes_node_storage_storage_content_volume.md) | +| POST | `/nodes/{node}/storage/{storage}/download-url` | [download_url](endpoints/POST_nodes_node_storage_storage_download_url.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/download` | [download](endpoints/GET_nodes_node_storage_storage_file_restore_download.md) | +| GET | `/nodes/{node}/storage/{storage}/file-restore/list` | [list](endpoints/GET_nodes_node_storage_storage_file_restore_list.md) | +| GET | `/nodes/{node}/storage/{storage}/identity` | [identity](endpoints/GET_nodes_node_storage_storage_identity.md) | +| GET | `/nodes/{node}/storage/{storage}/import-metadata` | [get_import_metadata](endpoints/GET_nodes_node_storage_storage_import_metadata.md) | +| POST | `/nodes/{node}/storage/{storage}/oci-registry-pull` | [oci_registry_pull](endpoints/POST_nodes_node_storage_storage_oci_registry_pull.md) | +| DELETE | `/nodes/{node}/storage/{storage}/prunebackups` | [delete](endpoints/DELETE_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/prunebackups` | [dryrun](endpoints/GET_nodes_node_storage_storage_prunebackups.md) | +| GET | `/nodes/{node}/storage/{storage}/rrd` | [rrd](endpoints/GET_nodes_node_storage_storage_rrd.md) | +| GET | `/nodes/{node}/storage/{storage}/rrddata` | [rrddata](endpoints/GET_nodes_node_storage_storage_rrddata.md) | +| GET | `/nodes/{node}/storage/{storage}/status` | [read_status](endpoints/GET_nodes_node_storage_storage_status.md) | +| POST | `/nodes/{node}/storage/{storage}/upload` | [upload](endpoints/POST_nodes_node_storage_storage_upload.md) | +| DELETE | `/nodes/{node}/subscription` | [delete](endpoints/DELETE_nodes_node_subscription.md) | +| GET | `/nodes/{node}/subscription` | [get](endpoints/GET_nodes_node_subscription.md) | +| POST | `/nodes/{node}/subscription` | [update](endpoints/POST_nodes_node_subscription.md) | +| PUT | `/nodes/{node}/subscription` | [set](endpoints/PUT_nodes_node_subscription.md) | +| POST | `/nodes/{node}/suspendall` | [suspendall](endpoints/POST_nodes_node_suspendall.md) | +| GET | `/nodes/{node}/syslog` | [syslog](endpoints/GET_nodes_node_syslog.md) | +| GET | `/nodes/{node}/tasks` | [node_tasks](endpoints/GET_nodes_node_tasks.md) | +| DELETE | `/nodes/{node}/tasks/{upid}` | [stop_task](endpoints/DELETE_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}` | [upid_index](endpoints/GET_nodes_node_tasks_upid.md) | +| GET | `/nodes/{node}/tasks/{upid}/log` | [read_task_log](endpoints/GET_nodes_node_tasks_upid_log.md) | +| GET | `/nodes/{node}/tasks/{upid}/status` | [read_task_status](endpoints/GET_nodes_node_tasks_upid_status.md) | +| POST | `/nodes/{node}/termproxy` | [termproxy](endpoints/POST_nodes_node_termproxy.md) | +| GET | `/nodes/{node}/time` | [time](endpoints/GET_nodes_node_time.md) | +| PUT | `/nodes/{node}/time` | [set_timezone](endpoints/PUT_nodes_node_time.md) | +| GET | `/nodes/{node}/version` | [version](endpoints/GET_nodes_node_version.md) | +| POST | `/nodes/{node}/vncshell` | [vncshell](endpoints/POST_nodes_node_vncshell.md) | +| GET | `/nodes/{node}/vncwebsocket` | [vncwebsocket](endpoints/GET_nodes_node_vncwebsocket.md) | +| POST | `/nodes/{node}/vzdump` | [vzdump](endpoints/POST_nodes_node_vzdump.md) | +| GET | `/nodes/{node}/vzdump/defaults` | [defaults](endpoints/GET_nodes_node_vzdump_defaults.md) | +| GET | `/nodes/{node}/vzdump/extractconfig` | [extractconfig](endpoints/GET_nodes_node_vzdump_extractconfig.md) | +| POST | `/nodes/{node}/wakeonlan` | [wakeonlan](endpoints/POST_nodes_node_wakeonlan.md) | diff --git a/docs/pve-api/markdown/pools.md b/docs/pve-api/markdown/pools.md new file mode 100644 index 00000000000..982e319581b --- /dev/null +++ b/docs/pve-api/markdown/pools.md @@ -0,0 +1,13 @@ +# /pools + +Endpoints in the `/pools` section. + +| Method | Path | Summary | +|---|---|---| +| DELETE | `/pools` | [delete_pool](endpoints/DELETE_pools.md) | +| GET | `/pools` | [index](endpoints/GET_pools.md) | +| POST | `/pools` | [create_pool](endpoints/POST_pools.md) | +| PUT | `/pools` | [update_pool](endpoints/PUT_pools.md) | +| DELETE | `/pools/{poolid}` | [delete_pool_deprecated](endpoints/DELETE_pools_poolid.md) | +| GET | `/pools/{poolid}` | [read_pool](endpoints/GET_pools_poolid.md) | +| PUT | `/pools/{poolid}` | [update_pool_deprecated](endpoints/PUT_pools_poolid.md) | diff --git a/docs/pve-api/markdown/storage.md b/docs/pve-api/markdown/storage.md new file mode 100644 index 00000000000..c10740f119b --- /dev/null +++ b/docs/pve-api/markdown/storage.md @@ -0,0 +1,11 @@ +# /storage + +Endpoints in the `/storage` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/storage` | [index](endpoints/GET_storage.md) | +| POST | `/storage` | [create](endpoints/POST_storage.md) | +| DELETE | `/storage/{storage}` | [delete](endpoints/DELETE_storage_storage.md) | +| GET | `/storage/{storage}` | [read](endpoints/GET_storage_storage.md) | +| PUT | `/storage/{storage}` | [update](endpoints/PUT_storage_storage.md) | diff --git a/docs/pve-api/markdown/version.md b/docs/pve-api/markdown/version.md new file mode 100644 index 00000000000..f537e9039ac --- /dev/null +++ b/docs/pve-api/markdown/version.md @@ -0,0 +1,7 @@ +# /version + +Endpoints in the `/version` section. + +| Method | Path | Summary | +|---|---|---| +| GET | `/version` | [version](endpoints/GET_version.md) | diff --git a/docs/pve-api/search-index.json b/docs/pve-api/search-index.json new file mode 100644 index 00000000000..92f36f46bf4 --- /dev/null +++ b/docs/pve-api/search-index.json @@ -0,0 +1,6077 @@ +[ + { + "id": "GET /access", + "title": "GET /access", + "method": "GET", + "path": "/access", + "section": "access", + "summary": "index", + "searchText": "GET\n/access\naccess\nindex\nDirectory index." + }, + { + "id": "GET /access/acl", + "title": "GET /access/acl", + "method": "GET", + "path": "/access/acl", + "section": "access", + "summary": "read_acl", + "searchText": "GET\n/access/acl\naccess\nread_acl\nGet Access Control List (ACLs)." + }, + { + "id": "PUT /access/acl", + "title": "PUT /access/acl", + "method": "PUT", + "path": "/access/acl", + "section": "access", + "summary": "update_acl", + "searchText": "PUT\n/access/acl\naccess\nupdate_acl\nUpdate Access Control List (add or remove permissions).\npath string Access control path\nroles string List of roles.\ndelete boolean Remove permissions (instead of adding it).\ngroups string List of groups.\npropagate boolean Allow to propagate (inherit) permissions.\ntokens string List of API tokens.\nusers string List of users." + }, + { + "id": "GET /access/domains", + "title": "GET /access/domains", + "method": "GET", + "path": "/access/domains", + "section": "access", + "summary": "index", + "searchText": "GET\n/access/domains\naccess\nindex\nAuthentication domain index." + }, + { + "id": "POST /access/domains", + "title": "POST /access/domains", + "method": "POST", + "path": "/access/domains", + "section": "access", + "summary": "create", + "searchText": "POST\n/access/domains\naccess\ncreate\nAdd an authentication server.\nrealm string Authentication domain ID\ntype string Realm type. ad ldap openid pam pve\nacr-values string Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.\naudiences string A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.\nautocreate boolean Automatically create users if they do not exist.\nbase_dn string LDAP base domain name\nbind_dn string LDAP bind domain name\ncapath string Path to the CA certificate store\ncase-sensitive boolean username is case-sensitive\ncert string Path to the client certificate\ncertkey string Path to the client certificate key\ncheck-connection boolean Check bind connection to the server.\nclient-id string OpenID Client ID\nclient-key string OpenID Client Key\ncomment string Description.\ndefault boolean Use this as default realm\ndomain string AD domain name\nfilter string LDAP filter for user sync.\ngroup_classes string The objectclasses for groups.\ngroup_dn string LDAP base domain name for group sync. If not set, the base_dn will be used.\ngroup_filter string LDAP filter for group sync.\ngroup_name_attr string LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.\ngroups-autocreate boolean Automatically create groups if they do not exist.\ngroups-claim string OpenID claim used to retrieve groups with.\ngroups-overwrite boolean All groups will be overwritten for the user on login.\nissuer-url string OpenID Issuer Url\nmode string LDAP protocol mode. ldap ldaps ldap+starttls\npassword string LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.\nport integer Server port.\nprompt string Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.\nquery-userinfo boolean Enables querying the userinfo endpoint for claims values.\nscopes string Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.\nsecure boolean Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.\nserver1 string Server IP address (or DNS name)\nserver2 string Fallback Server IP address (or DNS name)\nsslversion string LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! tlsv1 tlsv1_1 tlsv1_2 tlsv1_3\nsync_attributes string 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.\nsync-defaults-options string The default options for behavior of synchronizations.\ntfa string Use Two-factor authentication.\nuser_attr string LDAP user attribute name\nuser_classes string The objectclasses for users.\nusername-claim string OpenID claim used to generate the unique username.\nverify boolean Verify the server's SSL certificate" + }, + { + "id": "DELETE /access/domains/{realm}", + "title": "DELETE /access/domains/{realm}", + "method": "DELETE", + "path": "/access/domains/{realm}", + "section": "access", + "summary": "delete", + "searchText": "DELETE\n/access/domains/{realm}\naccess\ndelete\nDelete an authentication server.\nrealm string Authentication domain ID" + }, + { + "id": "GET /access/domains/{realm}", + "title": "GET /access/domains/{realm}", + "method": "GET", + "path": "/access/domains/{realm}", + "section": "access", + "summary": "read", + "searchText": "GET\n/access/domains/{realm}\naccess\nread\nGet auth server configuration.\nrealm string Authentication domain ID" + }, + { + "id": "PUT /access/domains/{realm}", + "title": "PUT /access/domains/{realm}", + "method": "PUT", + "path": "/access/domains/{realm}", + "section": "access", + "summary": "update", + "searchText": "PUT\n/access/domains/{realm}\naccess\nupdate\nUpdate authentication server settings.\nrealm string Authentication domain ID\nacr-values string Specifies the Authentication Context Class Reference values that theAuthorization Server is being requested to use for the Auth Request.\naudiences string A list of audiences that the OpenID Issuer may include that are accepted in addition to 'client-id'.\nautocreate boolean Automatically create users if they do not exist.\nbase_dn string LDAP base domain name\nbind_dn string LDAP bind domain name\ncapath string Path to the CA certificate store\ncase-sensitive boolean username is case-sensitive\ncert string Path to the client certificate\ncertkey string Path to the client certificate key\ncheck-connection boolean Check bind connection to the server.\nclient-id string OpenID Client ID\nclient-key string OpenID Client Key\ncomment string Description.\ndefault boolean Use this as default realm\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndomain string AD domain name\nfilter string LDAP filter for user sync.\ngroup_classes string The objectclasses for groups.\ngroup_dn string LDAP base domain name for group sync. If not set, the base_dn will be used.\ngroup_filter string LDAP filter for group sync.\ngroup_name_attr string LDAP attribute representing a groups name. If not set or found, the first value of the DN will be used as name.\ngroups-autocreate boolean Automatically create groups if they do not exist.\ngroups-claim string OpenID claim used to retrieve groups with.\ngroups-overwrite boolean All groups will be overwritten for the user on login.\nissuer-url string OpenID Issuer Url\nmode string LDAP protocol mode. ldap ldaps ldap+starttls\npassword string LDAP bind password. Will be stored in '/etc/pve/priv/realm/.pw'.\nport integer Server port.\nprompt string Specifies whether the Authorization Server prompts the End-User for reauthentication and consent.\nquery-userinfo boolean Enables querying the userinfo endpoint for claims values.\nscopes string Specifies the scopes (user details) that should be authorized and returned, for example 'email' or 'profile'.\nsecure boolean Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.\nserver1 string Server IP address (or DNS name)\nserver2 string Fallback Server IP address (or DNS name)\nsslversion string LDAPS TLS/SSL version. It's not recommended to use version older than 1.2! tlsv1 tlsv1_1 tlsv1_2 tlsv1_3\nsync_attributes string 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.\nsync-defaults-options string The default options for behavior of synchronizations.\ntfa string Use Two-factor authentication.\nuser_attr string LDAP user attribute name\nuser_classes string The objectclasses for users.\nverify boolean Verify the server's SSL certificate" + }, + { + "id": "POST /access/domains/{realm}/sync", + "title": "POST /access/domains/{realm}/sync", + "method": "POST", + "path": "/access/domains/{realm}/sync", + "section": "access", + "summary": "sync", + "searchText": "POST\n/access/domains/{realm}/sync\naccess\nsync\nSyncs 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.\nrealm string Authentication domain ID\nenable-new boolean Enable newly synced users immediately.\nfull boolean 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.\npurge boolean DEPRECATED: use 'remove-vanished' instead. Remove ACLs for users or groups which were removed from the config during a sync.\nremove-vanished string 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).\nscope string Select what to sync. users groups both\ndry-run boolean If set, does not write anything." + }, + { + "id": "GET /access/groups", + "title": "GET /access/groups", + "method": "GET", + "path": "/access/groups", + "section": "access", + "summary": "index", + "searchText": "GET\n/access/groups\naccess\nindex\nGroup index." + }, + { + "id": "POST /access/groups", + "title": "POST /access/groups", + "method": "POST", + "path": "/access/groups", + "section": "access", + "summary": "create_group", + "searchText": "POST\n/access/groups\naccess\ncreate_group\nCreate new group.\ngroupid string\ncomment string" + }, + { + "id": "DELETE /access/groups/{groupid}", + "title": "DELETE /access/groups/{groupid}", + "method": "DELETE", + "path": "/access/groups/{groupid}", + "section": "access", + "summary": "delete_group", + "searchText": "DELETE\n/access/groups/{groupid}\naccess\ndelete_group\nDelete group.\ngroupid string" + }, + { + "id": "GET /access/groups/{groupid}", + "title": "GET /access/groups/{groupid}", + "method": "GET", + "path": "/access/groups/{groupid}", + "section": "access", + "summary": "read_group", + "searchText": "GET\n/access/groups/{groupid}\naccess\nread_group\nGet group configuration.\ngroupid string" + }, + { + "id": "PUT /access/groups/{groupid}", + "title": "PUT /access/groups/{groupid}", + "method": "PUT", + "path": "/access/groups/{groupid}", + "section": "access", + "summary": "update_group", + "searchText": "PUT\n/access/groups/{groupid}\naccess\nupdate_group\nUpdate group data.\ngroupid string\ncomment string" + }, + { + "id": "GET /access/openid", + "title": "GET /access/openid", + "method": "GET", + "path": "/access/openid", + "section": "access", + "summary": "index", + "searchText": "GET\n/access/openid\naccess\nindex\nDirectory index." + }, + { + "id": "POST /access/openid/auth-url", + "title": "POST /access/openid/auth-url", + "method": "POST", + "path": "/access/openid/auth-url", + "section": "access", + "summary": "auth_url", + "searchText": "POST\n/access/openid/auth-url\naccess\nauth_url\nGet the OpenId Authorization Url for the specified realm.\nrealm string Authentication domain ID\nredirect-url string Redirection Url. The client should set this to the used server url (location.origin)." + }, + { + "id": "POST /access/openid/login", + "title": "POST /access/openid/login", + "method": "POST", + "path": "/access/openid/login", + "section": "access", + "summary": "login", + "searchText": "POST\n/access/openid/login\naccess\nlogin\nVerify OpenID authorization code and create a ticket.\ncode string OpenId authorization code.\nredirect-url string Redirection Url. The client should set this to the used server url (location.origin).\nstate string OpenId state." + }, + { + "id": "PUT /access/password", + "title": "PUT /access/password", + "method": "PUT", + "path": "/access/password", + "section": "access", + "summary": "change_password", + "searchText": "PUT\n/access/password\naccess\nchange_password\nChange user password.\npassword string The new password.\nuserid string Full User ID, in the `name@realm` format.\nconfirmation-password string The current password of the user performing the change." + }, + { + "id": "GET /access/permissions", + "title": "GET /access/permissions", + "method": "GET", + "path": "/access/permissions", + "section": "access", + "summary": "permissions", + "searchText": "GET\n/access/permissions\naccess\npermissions\nRetrieve effective permissions of given user/token.\npath string Only dump this specific path, not the whole tree.\nuserid string User ID or full API token ID" + }, + { + "id": "GET /access/roles", + "title": "GET /access/roles", + "method": "GET", + "path": "/access/roles", + "section": "access", + "summary": "index", + "searchText": "GET\n/access/roles\naccess\nindex\nRole index." + }, + { + "id": "POST /access/roles", + "title": "POST /access/roles", + "method": "POST", + "path": "/access/roles", + "section": "access", + "summary": "create_role", + "searchText": "POST\n/access/roles\naccess\ncreate_role\nCreate new role.\nroleid string\nprivs string" + }, + { + "id": "DELETE /access/roles/{roleid}", + "title": "DELETE /access/roles/{roleid}", + "method": "DELETE", + "path": "/access/roles/{roleid}", + "section": "access", + "summary": "delete_role", + "searchText": "DELETE\n/access/roles/{roleid}\naccess\ndelete_role\nDelete role.\nroleid string" + }, + { + "id": "GET /access/roles/{roleid}", + "title": "GET /access/roles/{roleid}", + "method": "GET", + "path": "/access/roles/{roleid}", + "section": "access", + "summary": "read_role", + "searchText": "GET\n/access/roles/{roleid}\naccess\nread_role\nGet role configuration.\nroleid string" + }, + { + "id": "PUT /access/roles/{roleid}", + "title": "PUT /access/roles/{roleid}", + "method": "PUT", + "path": "/access/roles/{roleid}", + "section": "access", + "summary": "update_role", + "searchText": "PUT\n/access/roles/{roleid}\naccess\nupdate_role\nUpdate an existing role.\nroleid string\nappend boolean\nprivs string" + }, + { + "id": "GET /access/tfa", + "title": "GET /access/tfa", + "method": "GET", + "path": "/access/tfa", + "section": "access", + "summary": "list_tfa", + "searchText": "GET\n/access/tfa\naccess\nlist_tfa\nList TFA configurations of users." + }, + { + "id": "GET /access/tfa/{userid}", + "title": "GET /access/tfa/{userid}", + "method": "GET", + "path": "/access/tfa/{userid}", + "section": "access", + "summary": "list_user_tfa", + "searchText": "GET\n/access/tfa/{userid}\naccess\nlist_user_tfa\nList TFA configurations of users.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "POST /access/tfa/{userid}", + "title": "POST /access/tfa/{userid}", + "method": "POST", + "path": "/access/tfa/{userid}", + "section": "access", + "summary": "add_tfa_entry", + "searchText": "POST\n/access/tfa/{userid}\naccess\nadd_tfa_entry\nAdd a TFA entry for a user.\nuserid string Full User ID, in the `name@realm` format.\ntype string TFA Entry Type. totp u2f webauthn recovery yubico\nchallenge string When responding to a u2f challenge: the original challenge string\ndescription string A description to distinguish multiple entries from one another\npassword string The current password of the user performing the change.\ntotp string A totp URI.\nvalue string The current value for the provided totp URI, or a Webauthn/U2F challenge response" + }, + { + "id": "DELETE /access/tfa/{userid}/{id}", + "title": "DELETE /access/tfa/{userid}/{id}", + "method": "DELETE", + "path": "/access/tfa/{userid}/{id}", + "section": "access", + "summary": "delete_tfa", + "searchText": "DELETE\n/access/tfa/{userid}/{id}\naccess\ndelete_tfa\nDelete a TFA entry by ID.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format.\npassword string The current password of the user performing the change." + }, + { + "id": "GET /access/tfa/{userid}/{id}", + "title": "GET /access/tfa/{userid}/{id}", + "method": "GET", + "path": "/access/tfa/{userid}/{id}", + "section": "access", + "summary": "get_tfa_entry", + "searchText": "GET\n/access/tfa/{userid}/{id}\naccess\nget_tfa_entry\nFetch a requested TFA entry if present.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "PUT /access/tfa/{userid}/{id}", + "title": "PUT /access/tfa/{userid}/{id}", + "method": "PUT", + "path": "/access/tfa/{userid}/{id}", + "section": "access", + "summary": "update_tfa_entry", + "searchText": "PUT\n/access/tfa/{userid}/{id}\naccess\nupdate_tfa_entry\nAdd a TFA entry for a user.\nid string A TFA entry id.\nuserid string Full User ID, in the `name@realm` format.\ndescription string A description to distinguish multiple entries from one another\nenable boolean Whether the entry should be enabled for login.\npassword string The current password of the user performing the change." + }, + { + "id": "GET /access/ticket", + "title": "GET /access/ticket", + "method": "GET", + "path": "/access/ticket", + "section": "access", + "summary": "get_ticket", + "searchText": "GET\n/access/ticket\naccess\nget_ticket\nDummy. Useful for formatters which want to provide a login page." + }, + { + "id": "POST /access/ticket", + "title": "POST /access/ticket", + "method": "POST", + "path": "/access/ticket", + "section": "access", + "summary": "create_ticket", + "searchText": "POST\n/access/ticket\naccess\ncreate_ticket\nCreate or verify authentication ticket.\npassword string The secret password. This can also be a valid ticket.\nusername string User name\nnew-format boolean This parameter is now ignored and assumed to be 1.\notp string One-time password for Two-factor authentication.\npath string Verify ticket, and check if user have access 'privs' on 'path'\nprivs string Verify ticket, and check if user have access 'privs' on 'path'\nrealm string You can optionally pass the realm using this parameter. Normally the realm is simply added to the username @.\ntfa-challenge string The signed TFA challenge string the user wants to respond to." + }, + { + "id": "GET /access/users", + "title": "GET /access/users", + "method": "GET", + "path": "/access/users", + "section": "access", + "summary": "index", + "searchText": "GET\n/access/users\naccess\nindex\nUser index.\nenabled boolean Optional filter for enable property.\nfull boolean Include group and token information." + }, + { + "id": "POST /access/users", + "title": "POST /access/users", + "method": "POST", + "path": "/access/users", + "section": "access", + "summary": "create_user", + "searchText": "POST\n/access/users\naccess\ncreate_user\nCreate new user.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\nemail string\nenable boolean Enable the account (default). You can set this to '0' to disable the account\nexpire integer Account expiration date (seconds since epoch). '0' means no expiration date.\nfirstname string\ngroups string\nkeys string Keys for two factor auth (yubico).\nlastname string\npassword string Initial password." + }, + { + "id": "DELETE /access/users/{userid}", + "title": "DELETE /access/users/{userid}", + "method": "DELETE", + "path": "/access/users/{userid}", + "section": "access", + "summary": "delete_user", + "searchText": "DELETE\n/access/users/{userid}\naccess\ndelete_user\nDelete user.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "GET /access/users/{userid}", + "title": "GET /access/users/{userid}", + "method": "GET", + "path": "/access/users/{userid}", + "section": "access", + "summary": "read_user", + "searchText": "GET\n/access/users/{userid}\naccess\nread_user\nGet user configuration.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "PUT /access/users/{userid}", + "title": "PUT /access/users/{userid}", + "method": "PUT", + "path": "/access/users/{userid}", + "section": "access", + "summary": "update_user", + "searchText": "PUT\n/access/users/{userid}\naccess\nupdate_user\nUpdate user configuration.\nuserid string Full User ID, in the `name@realm` format.\nappend boolean\ncomment string\nemail string\nenable boolean Enable the account (default). You can set this to '0' to disable the account\nexpire integer Account expiration date (seconds since epoch). '0' means no expiration date.\nfirstname string\ngroups string\nkeys string Keys for two factor auth (yubico).\nlastname string" + }, + { + "id": "GET /access/users/{userid}/tfa", + "title": "GET /access/users/{userid}/tfa", + "method": "GET", + "path": "/access/users/{userid}/tfa", + "section": "access", + "summary": "read_user_tfa_type", + "searchText": "GET\n/access/users/{userid}/tfa\naccess\nread_user_tfa_type\nGet user TFA types (Personal and Realm).\nuserid string Full User ID, in the `name@realm` format.\nmultiple boolean Request all entries as an array." + }, + { + "id": "GET /access/users/{userid}/token", + "title": "GET /access/users/{userid}/token", + "method": "GET", + "path": "/access/users/{userid}/token", + "section": "access", + "summary": "token_index", + "searchText": "GET\n/access/users/{userid}/token\naccess\ntoken_index\nGet user API tokens.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "DELETE /access/users/{userid}/token/{tokenid}", + "title": "DELETE /access/users/{userid}/token/{tokenid}", + "method": "DELETE", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "remove_token", + "searchText": "DELETE\n/access/users/{userid}/token/{tokenid}\naccess\nremove_token\nRemove API token for a specific user.\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "GET /access/users/{userid}/token/{tokenid}", + "title": "GET /access/users/{userid}/token/{tokenid}", + "method": "GET", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "read_token", + "searchText": "GET\n/access/users/{userid}/token/{tokenid}\naccess\nread_token\nGet specific API token information.\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "POST /access/users/{userid}/token/{tokenid}", + "title": "POST /access/users/{userid}/token/{tokenid}", + "method": "POST", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "generate_token", + "searchText": "POST\n/access/users/{userid}/token/{tokenid}\naccess\ngenerate_token\nGenerate a new API token for a specific user. NOTE: returns API token value, which needs to be stored as it cannot be retrieved afterwards!\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\nexpire integer API token expiration date (seconds since epoch). '0' means no expiration date.\nprivsep boolean Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user." + }, + { + "id": "PUT /access/users/{userid}/token/{tokenid}", + "title": "PUT /access/users/{userid}/token/{tokenid}", + "method": "PUT", + "path": "/access/users/{userid}/token/{tokenid}", + "section": "access", + "summary": "update_token_info", + "searchText": "PUT\n/access/users/{userid}/token/{tokenid}\naccess\nupdate_token_info\nUpdate 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!\ntokenid string User-specific token identifier.\nuserid string Full User ID, in the `name@realm` format.\ncomment string\ndelete string A list of settings you want to delete.\nexpire integer API token expiration date (seconds since epoch). '0' means no expiration date.\nprivsep boolean Restrict API token privileges with separate ACLs (default), or give full privileges of corresponding user.\nregenerate boolean Regenerate the token's secret value. All users of the previous secret will lose access after this operation." + }, + { + "id": "PUT /access/users/{userid}/unlock-tfa", + "title": "PUT /access/users/{userid}/unlock-tfa", + "method": "PUT", + "path": "/access/users/{userid}/unlock-tfa", + "section": "access", + "summary": "unlock_tfa", + "searchText": "PUT\n/access/users/{userid}/unlock-tfa\naccess\nunlock_tfa\nUnlock a user's TFA authentication.\nuserid string Full User ID, in the `name@realm` format." + }, + { + "id": "POST /access/vncticket", + "title": "POST /access/vncticket", + "method": "POST", + "path": "/access/vncticket", + "section": "access", + "summary": "verify_vnc_ticket", + "searchText": "POST\n/access/vncticket\naccess\nverify_vnc_ticket\nverify VNC authentication ticket.\nauthid string UserId or token\npath string Verify ticket, and check if user have access 'privs' on 'path'\nprivs string Verify ticket, and check if user have access 'privs' on 'path'\nvncticket string The VNC ticket.\nport integer Verify that the ticket is valid for this port." + }, + { + "id": "GET /cluster", + "title": "GET /cluster", + "method": "GET", + "path": "/cluster", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster\ncluster\nindex\nCluster index." + }, + { + "id": "GET /cluster/acme", + "title": "GET /cluster/acme", + "method": "GET", + "path": "/cluster/acme", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/acme\ncluster\nindex\nACMEAccount index." + }, + { + "id": "GET /cluster/acme/account", + "title": "GET /cluster/acme/account", + "method": "GET", + "path": "/cluster/acme/account", + "section": "cluster", + "summary": "account_index", + "searchText": "GET\n/cluster/acme/account\ncluster\naccount_index\nACMEAccount index." + }, + { + "id": "POST /cluster/acme/account", + "title": "POST /cluster/acme/account", + "method": "POST", + "path": "/cluster/acme/account", + "section": "cluster", + "summary": "register_account", + "searchText": "POST\n/cluster/acme/account\ncluster\nregister_account\nRegister a new ACME account with CA.\ncontact string Contact email addresses.\ndirectory string URL of ACME CA directory endpoint.\neab-hmac-key string HMAC key for External Account Binding.\neab-kid string Key Identifier for External Account Binding.\nname string ACME account config file name.\ntos_url string URL of CA TermsOfService - setting this indicates agreement." + }, + { + "id": "DELETE /cluster/acme/account/{name}", + "title": "DELETE /cluster/acme/account/{name}", + "method": "DELETE", + "path": "/cluster/acme/account/{name}", + "section": "cluster", + "summary": "deactivate_account", + "searchText": "DELETE\n/cluster/acme/account/{name}\ncluster\ndeactivate_account\nDeactivate existing ACME account at CA.\nname string ACME account config file name." + }, + { + "id": "GET /cluster/acme/account/{name}", + "title": "GET /cluster/acme/account/{name}", + "method": "GET", + "path": "/cluster/acme/account/{name}", + "section": "cluster", + "summary": "get_account", + "searchText": "GET\n/cluster/acme/account/{name}\ncluster\nget_account\nReturn existing ACME account information.\nname string ACME account config file name." + }, + { + "id": "PUT /cluster/acme/account/{name}", + "title": "PUT /cluster/acme/account/{name}", + "method": "PUT", + "path": "/cluster/acme/account/{name}", + "section": "cluster", + "summary": "update_account", + "searchText": "PUT\n/cluster/acme/account/{name}\ncluster\nupdate_account\nUpdate existing ACME account information with CA. Note: not specifying any new account information triggers a refresh.\nname string ACME account config file name.\ncontact string Contact email addresses." + }, + { + "id": "GET /cluster/acme/challenge-schema", + "title": "GET /cluster/acme/challenge-schema", + "method": "GET", + "path": "/cluster/acme/challenge-schema", + "section": "cluster", + "summary": "challengeschema", + "searchText": "GET\n/cluster/acme/challenge-schema\ncluster\nchallengeschema\nGet schema of ACME challenge types." + }, + { + "id": "GET /cluster/acme/directories", + "title": "GET /cluster/acme/directories", + "method": "GET", + "path": "/cluster/acme/directories", + "section": "cluster", + "summary": "get_directories", + "searchText": "GET\n/cluster/acme/directories\ncluster\nget_directories\nGet named known ACME directory endpoints." + }, + { + "id": "GET /cluster/acme/meta", + "title": "GET /cluster/acme/meta", + "method": "GET", + "path": "/cluster/acme/meta", + "section": "cluster", + "summary": "get_meta", + "searchText": "GET\n/cluster/acme/meta\ncluster\nget_meta\nRetrieve ACME Directory Meta Information\ndirectory string URL of ACME CA directory endpoint." + }, + { + "id": "GET /cluster/acme/plugins", + "title": "GET /cluster/acme/plugins", + "method": "GET", + "path": "/cluster/acme/plugins", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/acme/plugins\ncluster\nindex\nACME plugin index.\ntype string Only list ACME plugins of a specific type dns standalone" + }, + { + "id": "POST /cluster/acme/plugins", + "title": "POST /cluster/acme/plugins", + "method": "POST", + "path": "/cluster/acme/plugins", + "section": "cluster", + "summary": "add_plugin", + "searchText": "POST\n/cluster/acme/plugins\ncluster\nadd_plugin\nAdd ACME plugin configuration.\nid string ACME Plugin ID name\ntype string ACME challenge type. dns standalone\napi string API plugin name 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\ndata string DNS plugin data. (base64 encoded)\ndisable boolean Flag to disable the config.\nnodes string List of cluster node names.\nvalidation-delay integer Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records." + }, + { + "id": "DELETE /cluster/acme/plugins/{id}", + "title": "DELETE /cluster/acme/plugins/{id}", + "method": "DELETE", + "path": "/cluster/acme/plugins/{id}", + "section": "cluster", + "summary": "delete_plugin", + "searchText": "DELETE\n/cluster/acme/plugins/{id}\ncluster\ndelete_plugin\nDelete ACME plugin configuration.\nid string Unique identifier for ACME plugin instance." + }, + { + "id": "GET /cluster/acme/plugins/{id}", + "title": "GET /cluster/acme/plugins/{id}", + "method": "GET", + "path": "/cluster/acme/plugins/{id}", + "section": "cluster", + "summary": "get_plugin_config", + "searchText": "GET\n/cluster/acme/plugins/{id}\ncluster\nget_plugin_config\nGet ACME plugin configuration.\nid string Unique identifier for ACME plugin instance." + }, + { + "id": "PUT /cluster/acme/plugins/{id}", + "title": "PUT /cluster/acme/plugins/{id}", + "method": "PUT", + "path": "/cluster/acme/plugins/{id}", + "section": "cluster", + "summary": "update_plugin", + "searchText": "PUT\n/cluster/acme/plugins/{id}\ncluster\nupdate_plugin\nUpdate ACME plugin configuration.\nid string ACME Plugin ID name\napi string API plugin name 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\ndata string DNS plugin data. (base64 encoded)\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the config.\nnodes string List of cluster node names.\nvalidation-delay integer Extra delay in seconds to wait before requesting validation. Allows to cope with a long TTL of DNS records." + }, + { + "id": "GET /cluster/acme/tos", + "title": "GET /cluster/acme/tos", + "method": "GET", + "path": "/cluster/acme/tos", + "section": "cluster", + "summary": "get_tos", + "searchText": "GET\n/cluster/acme/tos\ncluster\nget_tos\nRetrieve ACME TermsOfService URL from CA. Deprecated, please use /cluster/acme/meta.\ndirectory string URL of ACME CA directory endpoint." + }, + { + "id": "GET /cluster/backup", + "title": "GET /cluster/backup", + "method": "GET", + "path": "/cluster/backup", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/backup\ncluster\nindex\nList vzdump backup schedule." + }, + { + "id": "POST /cluster/backup", + "title": "POST /cluster/backup", + "method": "POST", + "path": "/cluster/backup", + "section": "cluster", + "summary": "create_job", + "searchText": "POST\n/cluster/backup\ncluster\ncreate_job\nCreate new vzdump backup job.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncomment string Description for the Job.\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndow string Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.\ndumpdir string Store resulting files to specified directory.\nenabled boolean Enable or disable the job.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nid string Job ID (will be autogenerated).\nionice integer 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnode string Only run if executed on this node.\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nrepeat-missed boolean If true, the job will be run as soon as possible if it was missed while the scheduler was not running.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\nscript string Use specified hook script.\nstarttime string Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.\nstdexcludes boolean Exclude temporary files and logs.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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." + }, + { + "id": "GET /cluster/backup-info", + "title": "GET /cluster/backup-info", + "method": "GET", + "path": "/cluster/backup-info", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/backup-info\ncluster\nindex\nIndex for backup info related endpoints" + }, + { + "id": "GET /cluster/backup-info/not-backed-up", + "title": "GET /cluster/backup-info/not-backed-up", + "method": "GET", + "path": "/cluster/backup-info/not-backed-up", + "section": "cluster", + "summary": "get_guests_not_in_backup", + "searchText": "GET\n/cluster/backup-info/not-backed-up\ncluster\nget_guests_not_in_backup\nShows all guests which are not covered by any backup job." + }, + { + "id": "DELETE /cluster/backup/{id}", + "title": "DELETE /cluster/backup/{id}", + "method": "DELETE", + "path": "/cluster/backup/{id}", + "section": "cluster", + "summary": "delete_job", + "searchText": "DELETE\n/cluster/backup/{id}\ncluster\ndelete_job\nDelete vzdump backup job definition.\nid string The job ID." + }, + { + "id": "GET /cluster/backup/{id}", + "title": "GET /cluster/backup/{id}", + "method": "GET", + "path": "/cluster/backup/{id}", + "section": "cluster", + "summary": "read_job", + "searchText": "GET\n/cluster/backup/{id}\ncluster\nread_job\nRead vzdump backup job definition.\nid string The job ID." + }, + { + "id": "PUT /cluster/backup/{id}", + "title": "PUT /cluster/backup/{id}", + "method": "PUT", + "path": "/cluster/backup/{id}", + "section": "cluster", + "summary": "update_job", + "searchText": "PUT\n/cluster/backup/{id}\ncluster\nupdate_job\nUpdate vzdump backup job definition.\nid string The job ID.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncomment string Description for the Job.\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndelete string A list of settings you want to delete.\ndow string Deprecated: Use 'schedule' instead. Day of week selection. 'starttime' and 'dow' will be converted into 'schedule' if used.\ndumpdir string Store resulting files to specified directory.\nenabled boolean Enable or disable the job.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nionice integer 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnode string Only run if executed on this node.\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nrepeat-missed boolean If true, the job will be run as soon as possible if it was missed while the scheduler was not running.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\nscript string Use specified hook script.\nstarttime string Deprecated: Use 'schedule' instead. Job Start time. 'starttime' and 'dow' will be converted into 'schedule' if used.\nstdexcludes boolean Exclude temporary files and logs.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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." + }, + { + "id": "GET /cluster/backup/{id}/included_volumes", + "title": "GET /cluster/backup/{id}/included_volumes", + "method": "GET", + "path": "/cluster/backup/{id}/included_volumes", + "section": "cluster", + "summary": "get_volume_backup_included", + "searchText": "GET\n/cluster/backup/{id}/included_volumes\ncluster\nget_volume_backup_included\nReturns included guests and the backup status of their disks. Optimized to be used in ExtJS tree views.\nid string The job ID." + }, + { + "id": "GET /cluster/bulk-action", + "title": "GET /cluster/bulk-action", + "method": "GET", + "path": "/cluster/bulk-action", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/bulk-action\ncluster\nindex\nList resource types." + }, + { + "id": "GET /cluster/bulk-action/guest", + "title": "GET /cluster/bulk-action/guest", + "method": "GET", + "path": "/cluster/bulk-action/guest", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/bulk-action/guest\ncluster\nindex\nBulk action index." + }, + { + "id": "POST /cluster/bulk-action/guest/migrate", + "title": "POST /cluster/bulk-action/guest/migrate", + "method": "POST", + "path": "/cluster/bulk-action/guest/migrate", + "section": "cluster", + "summary": "migrate", + "searchText": "POST\n/cluster/bulk-action/guest/migrate\ncluster\nmigrate\nBulk migrate all guests on the cluster.\ntarget string Target node.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\nonline boolean Enable live migration for VMs and restart migration for CTs.\nvms array Only consider guests from this list of VMIDs.\nwith-local-disks boolean Enable live storage migration for local disk" + }, + { + "id": "POST /cluster/bulk-action/guest/shutdown", + "title": "POST /cluster/bulk-action/guest/shutdown", + "method": "POST", + "path": "/cluster/bulk-action/guest/shutdown", + "section": "cluster", + "summary": "shutdown", + "searchText": "POST\n/cluster/bulk-action/guest/shutdown\ncluster\nshutdown\nBulk shutdown all guests on the cluster.\nforce-stop boolean Makes sure the Guest stops after the timeout.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\ntimeout integer Default shutdown timeout in seconds if none is configured for the guest.\nvms array Only consider guests from this list of VMIDs." + }, + { + "id": "POST /cluster/bulk-action/guest/start", + "title": "POST /cluster/bulk-action/guest/start", + "method": "POST", + "path": "/cluster/bulk-action/guest/start", + "section": "cluster", + "summary": "start", + "searchText": "POST\n/cluster/bulk-action/guest/start\ncluster\nstart\nBulk start or resume all guests on the cluster.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\ntimeout integer Default start timeout in seconds. Only valid for VMs. (default depends on the guest configuration).\nvms array Only consider guests from this list of VMIDs." + }, + { + "id": "POST /cluster/bulk-action/guest/suspend", + "title": "POST /cluster/bulk-action/guest/suspend", + "method": "POST", + "path": "/cluster/bulk-action/guest/suspend", + "section": "cluster", + "summary": "suspend", + "searchText": "POST\n/cluster/bulk-action/guest/suspend\ncluster\nsuspend\nBulk suspend all guests on the cluster.\nmax-workers integer Defines the maximum number of tasks running concurrently.\nmaxworkers integer Defines the maximum number of tasks running concurrently. Deprecated, use 'max-workers' instead.\nstatestorage string The storage for the VM state.\nto-disk boolean If set, suspends the guests to disk. Will be resumed on next start.\nvms array Only consider guests from this list of VMIDs." + }, + { + "id": "GET /cluster/ceph", + "title": "GET /cluster/ceph", + "method": "GET", + "path": "/cluster/ceph", + "section": "cluster", + "summary": "cephindex", + "searchText": "GET\n/cluster/ceph\ncluster\ncephindex\nCluster ceph index." + }, + { + "id": "GET /cluster/ceph/flags", + "title": "GET /cluster/ceph/flags", + "method": "GET", + "path": "/cluster/ceph/flags", + "section": "cluster", + "summary": "get_all_flags", + "searchText": "GET\n/cluster/ceph/flags\ncluster\nget_all_flags\nget the status of all ceph flags" + }, + { + "id": "PUT /cluster/ceph/flags", + "title": "PUT /cluster/ceph/flags", + "method": "PUT", + "path": "/cluster/ceph/flags", + "section": "cluster", + "summary": "set_flags", + "searchText": "PUT\n/cluster/ceph/flags\ncluster\nset_flags\nSet/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.\nnobackfill boolean Backfilling of PGs is suspended.\nnodeep-scrub boolean Deep Scrubbing is disabled.\nnodown boolean OSD failure reports are being ignored, such that the monitors will not mark OSDs down.\nnoin boolean OSDs that were previously marked out will not be marked back in when they start.\nnoout boolean OSDs will not automatically be marked out after the configured interval.\nnorebalance boolean Rebalancing of PGs is suspended.\nnorecover boolean Recovery of PGs is suspended.\nnoscrub boolean Scrubbing is disabled.\nnotieragent boolean Cache tiering activity is suspended.\nnoup boolean OSDs are not allowed to start.\npause boolean Pauses read and writes." + }, + { + "id": "GET /cluster/ceph/flags/{flag}", + "title": "GET /cluster/ceph/flags/{flag}", + "method": "GET", + "path": "/cluster/ceph/flags/{flag}", + "section": "cluster", + "summary": "get_flag", + "searchText": "GET\n/cluster/ceph/flags/{flag}\ncluster\nget_flag\nGet the status of a specific ceph flag.\nflag string The name of the flag name to get. nobackfill nodeep-scrub nodown noin noout norebalance norecover noscrub notieragent noup pause" + }, + { + "id": "PUT /cluster/ceph/flags/{flag}", + "title": "PUT /cluster/ceph/flags/{flag}", + "method": "PUT", + "path": "/cluster/ceph/flags/{flag}", + "section": "cluster", + "summary": "update_flag", + "searchText": "PUT\n/cluster/ceph/flags/{flag}\ncluster\nupdate_flag\nSet or clear (unset) a specific Ceph flag. Runs synchronously (unlike the bulk PUT /cluster/ceph/flags endpoint, which forks a worker task).\nflag string The ceph flag to update nobackfill nodeep-scrub nodown noin noout norebalance norecover noscrub notieragent noup pause\nvalue boolean The new value of the flag" + }, + { + "id": "GET /cluster/ceph/metadata", + "title": "GET /cluster/ceph/metadata", + "method": "GET", + "path": "/cluster/ceph/metadata", + "section": "cluster", + "summary": "metadata", + "searchText": "GET\n/cluster/ceph/metadata\ncluster\nmetadata\nGet ceph metadata.\nscope string 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. all versions" + }, + { + "id": "GET /cluster/ceph/status", + "title": "GET /cluster/ceph/status", + "method": "GET", + "path": "/cluster/ceph/status", + "section": "cluster", + "summary": "status", + "searchText": "GET\n/cluster/ceph/status\ncluster\nstatus\nGet ceph status." + }, + { + "id": "GET /cluster/config", + "title": "GET /cluster/config", + "method": "GET", + "path": "/cluster/config", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/config\ncluster\nindex\nDirectory index." + }, + { + "id": "POST /cluster/config", + "title": "POST /cluster/config", + "method": "POST", + "path": "/cluster/config", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/config\ncluster\ncreate\nGenerate new cluster configuration. If no links given, default to local IP address as link0.\nclustername string The name of the cluster.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnodeid integer Node id for this node.\ntoken-coefficient integer Coefficient used to determine Corosync's token timeout. See the corosync.conf(5) manual for more details.\nvotes integer Number of votes for this node." + }, + { + "id": "GET /cluster/config/apiversion", + "title": "GET /cluster/config/apiversion", + "method": "GET", + "path": "/cluster/config/apiversion", + "section": "cluster", + "summary": "join_api_version", + "searchText": "GET\n/cluster/config/apiversion\ncluster\njoin_api_version\nReturn the version of the cluster join API available on this node." + }, + { + "id": "GET /cluster/config/join", + "title": "GET /cluster/config/join", + "method": "GET", + "path": "/cluster/config/join", + "section": "cluster", + "summary": "join_info", + "searchText": "GET\n/cluster/config/join\ncluster\njoin_info\nGet information needed to join this cluster over the connected node.\nnode string The node for which the joinee gets the nodeinfo." + }, + { + "id": "POST /cluster/config/join", + "title": "POST /cluster/config/join", + "method": "POST", + "path": "/cluster/config/join", + "section": "cluster", + "summary": "join", + "searchText": "POST\n/cluster/config/join\ncluster\njoin\nJoins 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).\nfingerprint string Certificate SHA 256 fingerprint.\nhostname string Hostname (or IP) of an existing cluster member.\npassword string Superuser (root) password of peer node.\nforce boolean Do not throw error if node already exists.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnodeid integer Node id for this node.\nvotes integer Number of votes for this node" + }, + { + "id": "GET /cluster/config/nodes", + "title": "GET /cluster/config/nodes", + "method": "GET", + "path": "/cluster/config/nodes", + "section": "cluster", + "summary": "nodes", + "searchText": "GET\n/cluster/config/nodes\ncluster\nnodes\nCorosync node list." + }, + { + "id": "DELETE /cluster/config/nodes/{node}", + "title": "DELETE /cluster/config/nodes/{node}", + "method": "DELETE", + "path": "/cluster/config/nodes/{node}", + "section": "cluster", + "summary": "delnode", + "searchText": "DELETE\n/cluster/config/nodes/{node}\ncluster\ndelnode\nRemoves a node from the cluster configuration.\nnode string The cluster node name." + }, + { + "id": "POST /cluster/config/nodes/{node}", + "title": "POST /cluster/config/nodes/{node}", + "method": "POST", + "path": "/cluster/config/nodes/{node}", + "section": "cluster", + "summary": "addnode", + "searchText": "POST\n/cluster/config/nodes/{node}\ncluster\naddnode\nAdds a node to the cluster configuration. This call is for internal use.\nnode string The cluster node name.\napiversion integer The JOIN_API_VERSION of the new node.\nforce boolean Do not throw error if node already exists.\nlink[n] string Address and priority information of a single corosync link. (up to 8 links supported; link0..link7)\nnew_node_ip string IP Address of node to add. Used as fallback if no links are given.\nnodeid integer Node id for this node.\nvotes integer Number of votes for this node" + }, + { + "id": "GET /cluster/config/qdevice", + "title": "GET /cluster/config/qdevice", + "method": "GET", + "path": "/cluster/config/qdevice", + "section": "cluster", + "summary": "status", + "searchText": "GET\n/cluster/config/qdevice\ncluster\nstatus\nGet QDevice status" + }, + { + "id": "GET /cluster/config/totem", + "title": "GET /cluster/config/totem", + "method": "GET", + "path": "/cluster/config/totem", + "section": "cluster", + "summary": "totem", + "searchText": "GET\n/cluster/config/totem\ncluster\ntotem\nGet corosync totem protocol settings." + }, + { + "id": "GET /cluster/firewall", + "title": "GET /cluster/firewall", + "method": "GET", + "path": "/cluster/firewall", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/firewall\ncluster\nindex\nDirectory index." + }, + { + "id": "GET /cluster/firewall/aliases", + "title": "GET /cluster/firewall/aliases", + "method": "GET", + "path": "/cluster/firewall/aliases", + "section": "cluster", + "summary": "get_aliases", + "searchText": "GET\n/cluster/firewall/aliases\ncluster\nget_aliases\nList aliases" + }, + { + "id": "POST /cluster/firewall/aliases", + "title": "POST /cluster/firewall/aliases", + "method": "POST", + "path": "/cluster/firewall/aliases", + "section": "cluster", + "summary": "create_alias", + "searchText": "POST\n/cluster/firewall/aliases\ncluster\ncreate_alias\nCreate IP or Network Alias.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string" + }, + { + "id": "DELETE /cluster/firewall/aliases/{name}", + "title": "DELETE /cluster/firewall/aliases/{name}", + "method": "DELETE", + "path": "/cluster/firewall/aliases/{name}", + "section": "cluster", + "summary": "remove_alias", + "searchText": "DELETE\n/cluster/firewall/aliases/{name}\ncluster\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/aliases/{name}", + "title": "GET /cluster/firewall/aliases/{name}", + "method": "GET", + "path": "/cluster/firewall/aliases/{name}", + "section": "cluster", + "summary": "read_alias", + "searchText": "GET\n/cluster/firewall/aliases/{name}\ncluster\nread_alias\nRead alias.\nname string Alias name." + }, + { + "id": "PUT /cluster/firewall/aliases/{name}", + "title": "PUT /cluster/firewall/aliases/{name}", + "method": "PUT", + "path": "/cluster/firewall/aliases/{name}", + "section": "cluster", + "summary": "update_alias", + "searchText": "PUT\n/cluster/firewall/aliases/{name}\ncluster\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias." + }, + { + "id": "GET /cluster/firewall/groups", + "title": "GET /cluster/firewall/groups", + "method": "GET", + "path": "/cluster/firewall/groups", + "section": "cluster", + "summary": "list_security_groups", + "searchText": "GET\n/cluster/firewall/groups\ncluster\nlist_security_groups\nList security groups." + }, + { + "id": "POST /cluster/firewall/groups", + "title": "POST /cluster/firewall/groups", + "method": "POST", + "path": "/cluster/firewall/groups", + "section": "cluster", + "summary": "create_security_group", + "searchText": "POST\n/cluster/firewall/groups\ncluster\ncreate_security_group\nCreate new security group.\ngroup string Security Group name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group." + }, + { + "id": "DELETE /cluster/firewall/groups/{group}", + "title": "DELETE /cluster/firewall/groups/{group}", + "method": "DELETE", + "path": "/cluster/firewall/groups/{group}", + "section": "cluster", + "summary": "delete_security_group", + "searchText": "DELETE\n/cluster/firewall/groups/{group}\ncluster\ndelete_security_group\nDelete security group.\ngroup string Security Group name." + }, + { + "id": "GET /cluster/firewall/groups/{group}", + "title": "GET /cluster/firewall/groups/{group}", + "method": "GET", + "path": "/cluster/firewall/groups/{group}", + "section": "cluster", + "summary": "get_rules", + "searchText": "GET\n/cluster/firewall/groups/{group}\ncluster\nget_rules\nList rules.\ngroup string Security Group name." + }, + { + "id": "POST /cluster/firewall/groups/{group}", + "title": "POST /cluster/firewall/groups/{group}", + "method": "POST", + "path": "/cluster/firewall/groups/{group}", + "section": "cluster", + "summary": "create_rule", + "searchText": "POST\n/cluster/firewall/groups/{group}\ncluster\ncreate_rule\nCreate new rule.\ngroup string Security Group name.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /cluster/firewall/groups/{group}/{pos}", + "title": "DELETE /cluster/firewall/groups/{group}/{pos}", + "method": "DELETE", + "path": "/cluster/firewall/groups/{group}/{pos}", + "section": "cluster", + "summary": "delete_rule", + "searchText": "DELETE\n/cluster/firewall/groups/{group}/{pos}\ncluster\ndelete_rule\nDelete rule.\ngroup string Security Group name.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/groups/{group}/{pos}", + "title": "GET /cluster/firewall/groups/{group}/{pos}", + "method": "GET", + "path": "/cluster/firewall/groups/{group}/{pos}", + "section": "cluster", + "summary": "get_rule", + "searchText": "GET\n/cluster/firewall/groups/{group}/{pos}\ncluster\nget_rule\nGet single rule data.\ngroup string Security Group name.\npos integer Update rule at position ." + }, + { + "id": "PUT /cluster/firewall/groups/{group}/{pos}", + "title": "PUT /cluster/firewall/groups/{group}/{pos}", + "method": "PUT", + "path": "/cluster/firewall/groups/{group}/{pos}", + "section": "cluster", + "summary": "update_rule", + "searchText": "PUT\n/cluster/firewall/groups/{group}/{pos}\ncluster\nupdate_rule\nModify rule data.\ngroup string Security Group name.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "GET /cluster/firewall/ipset", + "title": "GET /cluster/firewall/ipset", + "method": "GET", + "path": "/cluster/firewall/ipset", + "section": "cluster", + "summary": "ipset_index", + "searchText": "GET\n/cluster/firewall/ipset\ncluster\nipset_index\nList IPSets" + }, + { + "id": "POST /cluster/firewall/ipset", + "title": "POST /cluster/firewall/ipset", + "method": "POST", + "path": "/cluster/firewall/ipset", + "section": "cluster", + "summary": "create_ipset", + "searchText": "POST\n/cluster/firewall/ipset\ncluster\ncreate_ipset\nCreate new IPSet\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet." + }, + { + "id": "DELETE /cluster/firewall/ipset/{name}", + "title": "DELETE /cluster/firewall/ipset/{name}", + "method": "DELETE", + "path": "/cluster/firewall/ipset/{name}", + "section": "cluster", + "summary": "delete_ipset", + "searchText": "DELETE\n/cluster/firewall/ipset/{name}\ncluster\ndelete_ipset\nDelete IPSet\nname string IP set name.\nforce boolean Delete all members of the IPSet, if there are any." + }, + { + "id": "GET /cluster/firewall/ipset/{name}", + "title": "GET /cluster/firewall/ipset/{name}", + "method": "GET", + "path": "/cluster/firewall/ipset/{name}", + "section": "cluster", + "summary": "get_ipset", + "searchText": "GET\n/cluster/firewall/ipset/{name}\ncluster\nget_ipset\nList IPSet content\nname string IP set name." + }, + { + "id": "POST /cluster/firewall/ipset/{name}", + "title": "POST /cluster/firewall/ipset/{name}", + "method": "POST", + "path": "/cluster/firewall/ipset/{name}", + "section": "cluster", + "summary": "create_ip", + "searchText": "POST\n/cluster/firewall/ipset/{name}\ncluster\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean" + }, + { + "id": "DELETE /cluster/firewall/ipset/{name}/{cidr}", + "title": "DELETE /cluster/firewall/ipset/{name}/{cidr}", + "method": "DELETE", + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "section": "cluster", + "summary": "remove_ip", + "searchText": "DELETE\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/ipset/{name}/{cidr}", + "title": "GET /cluster/firewall/ipset/{name}/{cidr}", + "method": "GET", + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "section": "cluster", + "summary": "read_ip", + "searchText": "GET\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name." + }, + { + "id": "PUT /cluster/firewall/ipset/{name}/{cidr}", + "title": "PUT /cluster/firewall/ipset/{name}/{cidr}", + "method": "PUT", + "path": "/cluster/firewall/ipset/{name}/{cidr}", + "section": "cluster", + "summary": "update_ip", + "searchText": "PUT\n/cluster/firewall/ipset/{name}/{cidr}\ncluster\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean" + }, + { + "id": "GET /cluster/firewall/macros", + "title": "GET /cluster/firewall/macros", + "method": "GET", + "path": "/cluster/firewall/macros", + "section": "cluster", + "summary": "get_macros", + "searchText": "GET\n/cluster/firewall/macros\ncluster\nget_macros\nList available macros" + }, + { + "id": "GET /cluster/firewall/options", + "title": "GET /cluster/firewall/options", + "method": "GET", + "path": "/cluster/firewall/options", + "section": "cluster", + "summary": "get_options", + "searchText": "GET\n/cluster/firewall/options\ncluster\nget_options\nGet Firewall options." + }, + { + "id": "PUT /cluster/firewall/options", + "title": "PUT /cluster/firewall/options", + "method": "PUT", + "path": "/cluster/firewall/options", + "section": "cluster", + "summary": "set_options", + "searchText": "PUT\n/cluster/firewall/options\ncluster\nset_options\nSet Firewall options.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nebtables boolean Enable ebtables rules cluster wide.\nenable integer Enable or disable the firewall cluster wide.\nlog_ratelimit string Log ratelimiting settings\npolicy_forward string Forward policy. ACCEPT DROP\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP" + }, + { + "id": "GET /cluster/firewall/refs", + "title": "GET /cluster/firewall/refs", + "method": "GET", + "path": "/cluster/firewall/refs", + "section": "cluster", + "summary": "refs", + "searchText": "GET\n/cluster/firewall/refs\ncluster\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\ntype string Only list references of specified type. alias ipset" + }, + { + "id": "GET /cluster/firewall/rules", + "title": "GET /cluster/firewall/rules", + "method": "GET", + "path": "/cluster/firewall/rules", + "section": "cluster", + "summary": "get_rules", + "searchText": "GET\n/cluster/firewall/rules\ncluster\nget_rules\nList rules." + }, + { + "id": "POST /cluster/firewall/rules", + "title": "POST /cluster/firewall/rules", + "method": "POST", + "path": "/cluster/firewall/rules", + "section": "cluster", + "summary": "create_rule", + "searchText": "POST\n/cluster/firewall/rules\ncluster\ncreate_rule\nCreate new rule.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /cluster/firewall/rules/{pos}", + "title": "DELETE /cluster/firewall/rules/{pos}", + "method": "DELETE", + "path": "/cluster/firewall/rules/{pos}", + "section": "cluster", + "summary": "delete_rule", + "searchText": "DELETE\n/cluster/firewall/rules/{pos}\ncluster\ndelete_rule\nDelete rule.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/firewall/rules/{pos}", + "title": "GET /cluster/firewall/rules/{pos}", + "method": "GET", + "path": "/cluster/firewall/rules/{pos}", + "section": "cluster", + "summary": "get_rule", + "searchText": "GET\n/cluster/firewall/rules/{pos}\ncluster\nget_rule\nGet single rule data.\npos integer Update rule at position ." + }, + { + "id": "PUT /cluster/firewall/rules/{pos}", + "title": "PUT /cluster/firewall/rules/{pos}", + "method": "PUT", + "path": "/cluster/firewall/rules/{pos}", + "section": "cluster", + "summary": "update_rule", + "searchText": "PUT\n/cluster/firewall/rules/{pos}\ncluster\nupdate_rule\nModify rule data.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "GET /cluster/ha", + "title": "GET /cluster/ha", + "method": "GET", + "path": "/cluster/ha", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/ha\ncluster\nindex\nDirectory index." + }, + { + "id": "GET /cluster/ha/groups", + "title": "GET /cluster/ha/groups", + "method": "GET", + "path": "/cluster/ha/groups", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/ha/groups\ncluster\nindex\nGet HA groups. (deprecated in favor of HA rules)" + }, + { + "id": "POST /cluster/ha/groups", + "title": "POST /cluster/ha/groups", + "method": "POST", + "path": "/cluster/ha/groups", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/ha/groups\ncluster\ncreate\nCreate a new HA group. (deprecated in favor of HA rules)\ngroup string The HA group identifier.\nnodes string List of cluster node names with optional priority.\ncomment string Description.\nnofailback boolean 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.\nrestricted boolean Resources bound to restricted groups may only run on nodes defined by the group.\ntype string Group type. group" + }, + { + "id": "DELETE /cluster/ha/groups/{group}", + "title": "DELETE /cluster/ha/groups/{group}", + "method": "DELETE", + "path": "/cluster/ha/groups/{group}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/ha/groups/{group}\ncluster\ndelete\nDelete ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier." + }, + { + "id": "GET /cluster/ha/groups/{group}", + "title": "GET /cluster/ha/groups/{group}", + "method": "GET", + "path": "/cluster/ha/groups/{group}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/ha/groups/{group}\ncluster\nread\nRead ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier." + }, + { + "id": "PUT /cluster/ha/groups/{group}", + "title": "PUT /cluster/ha/groups/{group}", + "method": "PUT", + "path": "/cluster/ha/groups/{group}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/ha/groups/{group}\ncluster\nupdate\nUpdate ha group configuration. (deprecated in favor of HA rules)\ngroup string The HA group identifier.\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnodes string List of cluster node names with optional priority.\nnofailback boolean 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.\nrestricted boolean Resources bound to restricted groups may only run on nodes defined by the group." + }, + { + "id": "GET /cluster/ha/resources", + "title": "GET /cluster/ha/resources", + "method": "GET", + "path": "/cluster/ha/resources", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/ha/resources\ncluster\nindex\nList HA resources.\ntype string Only list resources of specific type ct vm" + }, + { + "id": "POST /cluster/ha/resources", + "title": "POST /cluster/ha/resources", + "method": "POST", + "path": "/cluster/ha/resources", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/ha/resources\ncluster\ncreate\nCreate a new HA resource.\nsid string 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).\nauto-rebalance boolean HA resource may be migrated during automatic rebalancing\ncomment string Description.\nfailback boolean 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.\ngroup string The HA group identifier.\nmax_relocate integer Maximal number of resource relocate tries when a resource fails to start.\nmax_restart integer 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.\nstate string Requested resource state. started stopped enabled disabled ignored\ntype string Resource type. ct vm" + }, + { + "id": "DELETE /cluster/ha/resources/{sid}", + "title": "DELETE /cluster/ha/resources/{sid}", + "method": "DELETE", + "path": "/cluster/ha/resources/{sid}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/ha/resources/{sid}\ncluster\ndelete\nDelete resource configuration.\nsid string 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).\npurge boolean Remove this resource from rules that reference it, deleting the rule if this resource is the only resource in the rule" + }, + { + "id": "GET /cluster/ha/resources/{sid}", + "title": "GET /cluster/ha/resources/{sid}", + "method": "GET", + "path": "/cluster/ha/resources/{sid}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/ha/resources/{sid}\ncluster\nread\nRead resource configuration.\nsid string 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)." + }, + { + "id": "PUT /cluster/ha/resources/{sid}", + "title": "PUT /cluster/ha/resources/{sid}", + "method": "PUT", + "path": "/cluster/ha/resources/{sid}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/ha/resources/{sid}\ncluster\nupdate\nUpdate resource configuration.\nsid string 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).\nauto-rebalance boolean HA resource may be migrated during automatic rebalancing\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfailback boolean 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.\ngroup string The HA group identifier.\nmax_relocate integer Maximal number of resource relocate tries when a resource fails to start.\nmax_restart integer 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.\nstate string Requested resource state. started stopped enabled disabled ignored" + }, + { + "id": "POST /cluster/ha/resources/{sid}/migrate", + "title": "POST /cluster/ha/resources/{sid}/migrate", + "method": "POST", + "path": "/cluster/ha/resources/{sid}/migrate", + "section": "cluster", + "summary": "migrate", + "searchText": "POST\n/cluster/ha/resources/{sid}/migrate\ncluster\nmigrate\nRequest resource migration (online) to another node.\nsid string 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).\nnode string Target node." + }, + { + "id": "POST /cluster/ha/resources/{sid}/relocate", + "title": "POST /cluster/ha/resources/{sid}/relocate", + "method": "POST", + "path": "/cluster/ha/resources/{sid}/relocate", + "section": "cluster", + "summary": "relocate", + "searchText": "POST\n/cluster/ha/resources/{sid}/relocate\ncluster\nrelocate\nRequest resource relocation to another node. This stops the service on the old node, and restarts it on the target node.\nsid string 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).\nnode string Target node." + }, + { + "id": "GET /cluster/ha/rules", + "title": "GET /cluster/ha/rules", + "method": "GET", + "path": "/cluster/ha/rules", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/ha/rules\ncluster\nindex\nGet HA rules.\nresource string Limit the returned list to rules affecting the specified resource.\ntype string Limit the returned list to the specified rule type. node-affinity resource-affinity" + }, + { + "id": "POST /cluster/ha/rules", + "title": "POST /cluster/ha/rules", + "method": "POST", + "path": "/cluster/ha/rules", + "section": "cluster", + "summary": "create_rule", + "searchText": "POST\n/cluster/ha/rules\ncluster\ncreate_rule\nCreate HA rule.\nresources string 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).\nrule string HA rule identifier.\ntype string HA rule type. node-affinity resource-affinity\naffinity string 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'). positive negative\ncomment string HA rule description.\ndisable boolean Whether the HA rule is disabled.\nnodes string List of cluster node names with optional priority.\nstrict boolean Describes whether the node affinity rule is strict or non-strict." + }, + { + "id": "DELETE /cluster/ha/rules/{rule}", + "title": "DELETE /cluster/ha/rules/{rule}", + "method": "DELETE", + "path": "/cluster/ha/rules/{rule}", + "section": "cluster", + "summary": "delete_rule", + "searchText": "DELETE\n/cluster/ha/rules/{rule}\ncluster\ndelete_rule\nDelete HA rule.\nrule string HA rule identifier." + }, + { + "id": "GET /cluster/ha/rules/{rule}", + "title": "GET /cluster/ha/rules/{rule}", + "method": "GET", + "path": "/cluster/ha/rules/{rule}", + "section": "cluster", + "summary": "read_rule", + "searchText": "GET\n/cluster/ha/rules/{rule}\ncluster\nread_rule\nRead HA rule.\nrule string HA rule identifier." + }, + { + "id": "PUT /cluster/ha/rules/{rule}", + "title": "PUT /cluster/ha/rules/{rule}", + "method": "PUT", + "path": "/cluster/ha/rules/{rule}", + "section": "cluster", + "summary": "update_rule", + "searchText": "PUT\n/cluster/ha/rules/{rule}\ncluster\nupdate_rule\nUpdate HA rule.\nrule string HA rule identifier.\ntype string HA rule type. node-affinity resource-affinity\naffinity string 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'). positive negative\ncomment string HA rule description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Whether the HA rule is disabled.\nnodes string List of cluster node names with optional priority.\nresources string 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).\nstrict boolean Describes whether the node affinity rule is strict or non-strict." + }, + { + "id": "GET /cluster/ha/status", + "title": "GET /cluster/ha/status", + "method": "GET", + "path": "/cluster/ha/status", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/ha/status\ncluster\nindex\nDirectory index." + }, + { + "id": "POST /cluster/ha/status/arm-ha", + "title": "POST /cluster/ha/status/arm-ha", + "method": "POST", + "path": "/cluster/ha/status/arm-ha", + "section": "cluster", + "summary": "arm-ha", + "searchText": "POST\n/cluster/ha/status/arm-ha\ncluster\narm-ha\nRequest re-arming the HA stack after it was disarmed." + }, + { + "id": "GET /cluster/ha/status/current", + "title": "GET /cluster/ha/status/current", + "method": "GET", + "path": "/cluster/ha/status/current", + "section": "cluster", + "summary": "status", + "searchText": "GET\n/cluster/ha/status/current\ncluster\nstatus\nGet HA manager status." + }, + { + "id": "POST /cluster/ha/status/disarm-ha", + "title": "POST /cluster/ha/status/disarm-ha", + "method": "POST", + "path": "/cluster/ha/status/disarm-ha", + "section": "cluster", + "summary": "disarm-ha", + "searchText": "POST\n/cluster/ha/status/disarm-ha\ncluster\ndisarm-ha\nRequest disarming the HA stack, releasing all watchdogs cluster-wide.\nresource-mode string 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. freeze ignore" + }, + { + "id": "GET /cluster/ha/status/manager_status", + "title": "GET /cluster/ha/status/manager_status", + "method": "GET", + "path": "/cluster/ha/status/manager_status", + "section": "cluster", + "summary": "manager_status", + "searchText": "GET\n/cluster/ha/status/manager_status\ncluster\nmanager_status\nGet full HA manager status, including LRM status." + }, + { + "id": "GET /cluster/jobs", + "title": "GET /cluster/jobs", + "method": "GET", + "path": "/cluster/jobs", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/jobs\ncluster\nindex\nIndex for jobs related endpoints." + }, + { + "id": "GET /cluster/jobs/realm-sync", + "title": "GET /cluster/jobs/realm-sync", + "method": "GET", + "path": "/cluster/jobs/realm-sync", + "section": "cluster", + "summary": "syncjob_index", + "searchText": "GET\n/cluster/jobs/realm-sync\ncluster\nsyncjob_index\nList configured realm-sync-jobs." + }, + { + "id": "DELETE /cluster/jobs/realm-sync/{id}", + "title": "DELETE /cluster/jobs/realm-sync/{id}", + "method": "DELETE", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "delete_job", + "searchText": "DELETE\n/cluster/jobs/realm-sync/{id}\ncluster\ndelete_job\nDelete realm-sync job definition.\nid string" + }, + { + "id": "GET /cluster/jobs/realm-sync/{id}", + "title": "GET /cluster/jobs/realm-sync/{id}", + "method": "GET", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "read_job", + "searchText": "GET\n/cluster/jobs/realm-sync/{id}\ncluster\nread_job\nRead realm-sync job definition.\nid string" + }, + { + "id": "POST /cluster/jobs/realm-sync/{id}", + "title": "POST /cluster/jobs/realm-sync/{id}", + "method": "POST", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "create_job", + "searchText": "POST\n/cluster/jobs/realm-sync/{id}\ncluster\ncreate_job\nCreate new realm-sync job.\nid string The ID of the job.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\ncomment string Description for the Job.\nenable-new boolean Enable newly synced users immediately.\nenabled boolean Determines if the job is enabled.\nrealm string Authentication domain ID\nremove-vanished string 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).\nscope string Select what to sync. users groups both" + }, + { + "id": "PUT /cluster/jobs/realm-sync/{id}", + "title": "PUT /cluster/jobs/realm-sync/{id}", + "method": "PUT", + "path": "/cluster/jobs/realm-sync/{id}", + "section": "cluster", + "summary": "update_job", + "searchText": "PUT\n/cluster/jobs/realm-sync/{id}\ncluster\nupdate_job\nUpdate realm-sync job definition.\nid string The ID of the job.\nschedule string Backup schedule. The format is a subset of `systemd` calendar events.\ncomment string Description for the Job.\ndelete string A list of settings you want to delete.\nenable-new boolean Enable newly synced users immediately.\nenabled boolean Determines if the job is enabled.\nremove-vanished string 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).\nscope string Select what to sync. users groups both" + }, + { + "id": "GET /cluster/jobs/schedule-analyze", + "title": "GET /cluster/jobs/schedule-analyze", + "method": "GET", + "path": "/cluster/jobs/schedule-analyze", + "section": "cluster", + "summary": "schedule-analyze", + "searchText": "GET\n/cluster/jobs/schedule-analyze\ncluster\nschedule-analyze\nReturns a list of future schedule runtimes.\nschedule string Job schedule. The format is a subset of `systemd` calendar events.\niterations integer Number of event-iteration to simulate and return.\nstarttime integer UNIX timestamp to start the calculation from. Defaults to the current time." + }, + { + "id": "GET /cluster/log", + "title": "GET /cluster/log", + "method": "GET", + "path": "/cluster/log", + "section": "cluster", + "summary": "log", + "searchText": "GET\n/cluster/log\ncluster\nlog\nRead cluster log\nmax integer Maximum number of entries." + }, + { + "id": "GET /cluster/mapping", + "title": "GET /cluster/mapping", + "method": "GET", + "path": "/cluster/mapping", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/mapping\ncluster\nindex\nList resource types." + }, + { + "id": "GET /cluster/mapping/dir", + "title": "GET /cluster/mapping/dir", + "method": "GET", + "path": "/cluster/mapping/dir", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/mapping/dir\ncluster\nindex\nList directory mapping\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the directory to the response." + }, + { + "id": "POST /cluster/mapping/dir", + "title": "POST /cluster/mapping/dir", + "method": "POST", + "path": "/cluster/mapping/dir", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/mapping/dir\ncluster\ncreate\nCreate a new directory mapping.\nid string The ID of the directory mapping\nmap array A list of maps for the cluster nodes.\ndescription string Description of the directory mapping" + }, + { + "id": "DELETE /cluster/mapping/dir/{id}", + "title": "DELETE /cluster/mapping/dir/{id}", + "method": "DELETE", + "path": "/cluster/mapping/dir/{id}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/mapping/dir/{id}\ncluster\ndelete\nRemove directory mapping.\nid string" + }, + { + "id": "GET /cluster/mapping/dir/{id}", + "title": "GET /cluster/mapping/dir/{id}", + "method": "GET", + "path": "/cluster/mapping/dir/{id}", + "section": "cluster", + "summary": "get", + "searchText": "GET\n/cluster/mapping/dir/{id}\ncluster\nget\nGet directory mapping.\nid string" + }, + { + "id": "PUT /cluster/mapping/dir/{id}", + "title": "PUT /cluster/mapping/dir/{id}", + "method": "PUT", + "path": "/cluster/mapping/dir/{id}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/mapping/dir/{id}\ncluster\nupdate\nUpdate a directory mapping.\nid string The ID of the directory mapping\ndelete string A list of settings you want to delete.\ndescription string Description of the directory mapping\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nmap array A list of maps for the cluster nodes." + }, + { + "id": "GET /cluster/mapping/pci", + "title": "GET /cluster/mapping/pci", + "method": "GET", + "path": "/cluster/mapping/pci", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/mapping/pci\ncluster\nindex\nList PCI Hardware Mapping\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant diagnostics for the devices to the response." + }, + { + "id": "POST /cluster/mapping/pci", + "title": "POST /cluster/mapping/pci", + "method": "POST", + "path": "/cluster/mapping/pci", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/mapping/pci\ncluster\ncreate\nCreate a new hardware mapping.\nid string The ID of the logical PCI mapping.\nmap array A list of maps for the cluster nodes.\ndescription string Description of the logical PCI device.\nlive-migration-capable boolean Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.\nmdev boolean Marks the device(s) as being capable of providing mediated devices." + }, + { + "id": "DELETE /cluster/mapping/pci/{id}", + "title": "DELETE /cluster/mapping/pci/{id}", + "method": "DELETE", + "path": "/cluster/mapping/pci/{id}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/mapping/pci/{id}\ncluster\ndelete\nRemove Hardware Mapping.\nid string" + }, + { + "id": "GET /cluster/mapping/pci/{id}", + "title": "GET /cluster/mapping/pci/{id}", + "method": "GET", + "path": "/cluster/mapping/pci/{id}", + "section": "cluster", + "summary": "get", + "searchText": "GET\n/cluster/mapping/pci/{id}\ncluster\nget\nGet PCI Mapping.\nid string" + }, + { + "id": "PUT /cluster/mapping/pci/{id}", + "title": "PUT /cluster/mapping/pci/{id}", + "method": "PUT", + "path": "/cluster/mapping/pci/{id}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/mapping/pci/{id}\ncluster\nupdate\nUpdate a hardware mapping.\nid string The ID of the logical PCI mapping.\ndelete string A list of settings you want to delete.\ndescription string Description of the logical PCI device.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nlive-migration-capable boolean Marks the device(s) as being able to be live-migrated (Experimental). This needs hardware and driver support to work.\nmap array A list of maps for the cluster nodes.\nmdev boolean Marks the device(s) as being capable of providing mediated devices." + }, + { + "id": "GET /cluster/mapping/usb", + "title": "GET /cluster/mapping/usb", + "method": "GET", + "path": "/cluster/mapping/usb", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/mapping/usb\ncluster\nindex\nList USB Hardware Mappings\ncheck-node string If given, checks the configurations on the given node for correctness, and adds relevant errors to the devices." + }, + { + "id": "POST /cluster/mapping/usb", + "title": "POST /cluster/mapping/usb", + "method": "POST", + "path": "/cluster/mapping/usb", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/mapping/usb\ncluster\ncreate\nCreate a new hardware mapping.\nid string The ID of the logical USB mapping.\nmap array A list of maps for the cluster nodes.\ndescription string Description of the logical USB device." + }, + { + "id": "DELETE /cluster/mapping/usb/{id}", + "title": "DELETE /cluster/mapping/usb/{id}", + "method": "DELETE", + "path": "/cluster/mapping/usb/{id}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/mapping/usb/{id}\ncluster\ndelete\nRemove Hardware Mapping.\nid string" + }, + { + "id": "GET /cluster/mapping/usb/{id}", + "title": "GET /cluster/mapping/usb/{id}", + "method": "GET", + "path": "/cluster/mapping/usb/{id}", + "section": "cluster", + "summary": "get", + "searchText": "GET\n/cluster/mapping/usb/{id}\ncluster\nget\nGet USB Mapping.\nid string" + }, + { + "id": "PUT /cluster/mapping/usb/{id}", + "title": "PUT /cluster/mapping/usb/{id}", + "method": "PUT", + "path": "/cluster/mapping/usb/{id}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/mapping/usb/{id}\ncluster\nupdate\nUpdate a hardware mapping.\nid string The ID of the logical USB mapping.\nmap array A list of maps for the cluster nodes.\ndelete string A list of settings you want to delete.\ndescription string Description of the logical USB device.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/metrics", + "title": "GET /cluster/metrics", + "method": "GET", + "path": "/cluster/metrics", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/metrics\ncluster\nindex\nMetrics index." + }, + { + "id": "GET /cluster/metrics/export", + "title": "GET /cluster/metrics/export", + "method": "GET", + "path": "/cluster/metrics/export", + "section": "cluster", + "summary": "export", + "searchText": "GET\n/cluster/metrics/export\ncluster\nexport\nRetrieve metrics of the cluster.\nhistory boolean Also return historic values. Returns full available metric history unless `start-time` is also set\nlocal-only boolean Only return metrics for the current node instead of the whole cluster\nnode-list string Only return metrics from nodes passed as comma-separated list\nstart-time integer Only include metrics with a timestamp > start-time." + }, + { + "id": "GET /cluster/metrics/server", + "title": "GET /cluster/metrics/server", + "method": "GET", + "path": "/cluster/metrics/server", + "section": "cluster", + "summary": "server_index", + "searchText": "GET\n/cluster/metrics/server\ncluster\nserver_index\nList configured metric servers." + }, + { + "id": "DELETE /cluster/metrics/server/{id}", + "title": "DELETE /cluster/metrics/server/{id}", + "method": "DELETE", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/metrics/server/{id}\ncluster\ndelete\nRemove Metric server.\nid string" + }, + { + "id": "GET /cluster/metrics/server/{id}", + "title": "GET /cluster/metrics/server/{id}", + "method": "GET", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/metrics/server/{id}\ncluster\nread\nRead metric server configuration.\nid string" + }, + { + "id": "POST /cluster/metrics/server/{id}", + "title": "POST /cluster/metrics/server/{id}", + "method": "POST", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/metrics/server/{id}\ncluster\ncreate\nCreate a new external metric server config\nid string The ID of the entry.\nport integer server network port\nserver string server dns name or IP address\ntype string Plugin type. graphite influxdb opentelemetry\napi-path-prefix string An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.\nbucket string The InfluxDB bucket/db. Only necessary when using the http v2 api.\ndisable boolean Flag to disable the plugin.\ninfluxdbproto string udp http https\nmax-body-size integer InfluxDB max-body-size in bytes. Requests are batched up to this size.\nmtu integer MTU for metrics transmission over UDP\norganization string The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.\notel-compression string Compression algorithm for requests none gzip\notel-headers string Custom HTTP headers (JSON format, base64 encoded)\notel-max-body-size integer Maximum request body size in bytes\notel-path string OTLP endpoint path\notel-protocol string HTTP protocol http https\notel-resource-attributes string Additional resource attributes as JSON, base64 encoded\notel-timeout integer HTTP request timeout in seconds\notel-verify-ssl boolean Verify SSL certificates\npath string root graphite path (ex: proxmox.mycluster.mykey)\nproto string Protocol to send graphite data. TCP or UDP (default) udp tcp\ntimeout integer graphite TCP socket timeout (default=1)\ntoken string The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.\nverify-certificate boolean Set to 0 to disable certificate verification for https endpoints." + }, + { + "id": "PUT /cluster/metrics/server/{id}", + "title": "PUT /cluster/metrics/server/{id}", + "method": "PUT", + "path": "/cluster/metrics/server/{id}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/metrics/server/{id}\ncluster\nupdate\nUpdate metric server configuration.\nid string The ID of the entry.\nport integer server network port\nserver string server dns name or IP address\napi-path-prefix string An API path prefix inserted between ':/' and '/api2/'. Can be useful if the InfluxDB service runs behind a reverse proxy.\nbucket string The InfluxDB bucket/db. Only necessary when using the http v2 api.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the plugin.\ninfluxdbproto string udp http https\nmax-body-size integer InfluxDB max-body-size in bytes. Requests are batched up to this size.\nmtu integer MTU for metrics transmission over UDP\norganization string The InfluxDB organization. Only necessary when using the http v2 api. Has no meaning when using v2 compatibility api.\notel-compression string Compression algorithm for requests none gzip\notel-headers string Custom HTTP headers (JSON format, base64 encoded)\notel-max-body-size integer Maximum request body size in bytes\notel-path string OTLP endpoint path\notel-protocol string HTTP protocol http https\notel-resource-attributes string Additional resource attributes as JSON, base64 encoded\notel-timeout integer HTTP request timeout in seconds\notel-verify-ssl boolean Verify SSL certificates\npath string root graphite path (ex: proxmox.mycluster.mykey)\nproto string Protocol to send graphite data. TCP or UDP (default) udp tcp\ntimeout integer graphite TCP socket timeout (default=1)\ntoken string The InfluxDB access token. Only necessary when using the http v2 api. If the v2 compatibility api is used, use 'user:password' instead.\nverify-certificate boolean Set to 0 to disable certificate verification for https endpoints." + }, + { + "id": "GET /cluster/nextid", + "title": "GET /cluster/nextid", + "method": "GET", + "path": "/cluster/nextid", + "section": "cluster", + "summary": "nextid", + "searchText": "GET\n/cluster/nextid\ncluster\nnextid\nGet next free VMID. Pass a VMID to assert that its free (at time of check).\nvmid integer The (unique) ID of the VM." + }, + { + "id": "GET /cluster/notifications", + "title": "GET /cluster/notifications", + "method": "GET", + "path": "/cluster/notifications", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/notifications\ncluster\nindex\nIndex for notification-related API endpoints." + }, + { + "id": "GET /cluster/notifications/endpoints", + "title": "GET /cluster/notifications/endpoints", + "method": "GET", + "path": "/cluster/notifications/endpoints", + "section": "cluster", + "summary": "endpoints_index", + "searchText": "GET\n/cluster/notifications/endpoints\ncluster\nendpoints_index\nIndex for all available endpoint types." + }, + { + "id": "GET /cluster/notifications/endpoints/gotify", + "title": "GET /cluster/notifications/endpoints/gotify", + "method": "GET", + "path": "/cluster/notifications/endpoints/gotify", + "section": "cluster", + "summary": "get_gotify_endpoints", + "searchText": "GET\n/cluster/notifications/endpoints/gotify\ncluster\nget_gotify_endpoints\nReturns a list of all gotify endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/gotify", + "title": "POST /cluster/notifications/endpoints/gotify", + "method": "POST", + "path": "/cluster/notifications/endpoints/gotify", + "section": "cluster", + "summary": "create_gotify_endpoint", + "searchText": "POST\n/cluster/notifications/endpoints/gotify\ncluster\ncreate_gotify_endpoint\nCreate a new gotify endpoint\nname string The name of the endpoint.\nserver string Server URL\ntoken string Secret token\ncomment string Comment\ndisable boolean Disable this target" + }, + { + "id": "DELETE /cluster/notifications/endpoints/gotify/{name}", + "title": "DELETE /cluster/notifications/endpoints/gotify/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/gotify/{name}", + "section": "cluster", + "summary": "delete_gotify_endpoint", + "searchText": "DELETE\n/cluster/notifications/endpoints/gotify/{name}\ncluster\ndelete_gotify_endpoint\nRemove gotify endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/gotify/{name}", + "title": "GET /cluster/notifications/endpoints/gotify/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/gotify/{name}", + "section": "cluster", + "summary": "get_gotify_endpoint", + "searchText": "GET\n/cluster/notifications/endpoints/gotify/{name}\ncluster\nget_gotify_endpoint\nReturn a specific gotify endpoint\nname string Name of the endpoint." + }, + { + "id": "PUT /cluster/notifications/endpoints/gotify/{name}", + "title": "PUT /cluster/notifications/endpoints/gotify/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/gotify/{name}", + "section": "cluster", + "summary": "update_gotify_endpoint", + "searchText": "PUT\n/cluster/notifications/endpoints/gotify/{name}\ncluster\nupdate_gotify_endpoint\nUpdate existing gotify endpoint\nname string The name of the endpoint.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nserver string Server URL\ntoken string Secret token" + }, + { + "id": "GET /cluster/notifications/endpoints/sendmail", + "title": "GET /cluster/notifications/endpoints/sendmail", + "method": "GET", + "path": "/cluster/notifications/endpoints/sendmail", + "section": "cluster", + "summary": "get_sendmail_endpoints", + "searchText": "GET\n/cluster/notifications/endpoints/sendmail\ncluster\nget_sendmail_endpoints\nReturns a list of all sendmail endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/sendmail", + "title": "POST /cluster/notifications/endpoints/sendmail", + "method": "POST", + "path": "/cluster/notifications/endpoints/sendmail", + "section": "cluster", + "summary": "create_sendmail_endpoint", + "searchText": "POST\n/cluster/notifications/endpoints/sendmail\ncluster\ncreate_sendmail_endpoint\nCreate a new sendmail endpoint\nname string The name of the endpoint.\nauthor string Author of the mail\ncomment string Comment\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users" + }, + { + "id": "DELETE /cluster/notifications/endpoints/sendmail/{name}", + "title": "DELETE /cluster/notifications/endpoints/sendmail/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "section": "cluster", + "summary": "delete_sendmail_endpoint", + "searchText": "DELETE\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\ndelete_sendmail_endpoint\nRemove sendmail endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/sendmail/{name}", + "title": "GET /cluster/notifications/endpoints/sendmail/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "section": "cluster", + "summary": "get_sendmail_endpoint", + "searchText": "GET\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\nget_sendmail_endpoint\nReturn a specific sendmail endpoint\nname string" + }, + { + "id": "PUT /cluster/notifications/endpoints/sendmail/{name}", + "title": "PUT /cluster/notifications/endpoints/sendmail/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/sendmail/{name}", + "section": "cluster", + "summary": "update_sendmail_endpoint", + "searchText": "PUT\n/cluster/notifications/endpoints/sendmail/{name}\ncluster\nupdate_sendmail_endpoint\nUpdate existing sendmail endpoint\nname string The name of the endpoint.\nauthor string Author of the mail\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users" + }, + { + "id": "GET /cluster/notifications/endpoints/smtp", + "title": "GET /cluster/notifications/endpoints/smtp", + "method": "GET", + "path": "/cluster/notifications/endpoints/smtp", + "section": "cluster", + "summary": "get_smtp_endpoints", + "searchText": "GET\n/cluster/notifications/endpoints/smtp\ncluster\nget_smtp_endpoints\nReturns a list of all smtp endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/smtp", + "title": "POST /cluster/notifications/endpoints/smtp", + "method": "POST", + "path": "/cluster/notifications/endpoints/smtp", + "section": "cluster", + "summary": "create_smtp_endpoint", + "searchText": "POST\n/cluster/notifications/endpoints/smtp\ncluster\ncreate_smtp_endpoint\nCreate a new smtp endpoint\nfrom-address string `From` address for the mail\nname string The name of the endpoint.\nserver string The address of the SMTP server.\nauthor string Author of the mail. Defaults to 'Proxmox VE'.\ncomment string Comment\ndisable boolean Disable this target\nmailto array List of email recipients\nmailto-user array List of users\nmode string Determine which encryption method shall be used for the connection. insecure starttls tls\npassword string Password for SMTP authentication\nport integer 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.\nusername string Username for SMTP authentication" + }, + { + "id": "DELETE /cluster/notifications/endpoints/smtp/{name}", + "title": "DELETE /cluster/notifications/endpoints/smtp/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/smtp/{name}", + "section": "cluster", + "summary": "delete_smtp_endpoint", + "searchText": "DELETE\n/cluster/notifications/endpoints/smtp/{name}\ncluster\ndelete_smtp_endpoint\nRemove smtp endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/smtp/{name}", + "title": "GET /cluster/notifications/endpoints/smtp/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/smtp/{name}", + "section": "cluster", + "summary": "get_smtp_endpoint", + "searchText": "GET\n/cluster/notifications/endpoints/smtp/{name}\ncluster\nget_smtp_endpoint\nReturn a specific smtp endpoint\nname string" + }, + { + "id": "PUT /cluster/notifications/endpoints/smtp/{name}", + "title": "PUT /cluster/notifications/endpoints/smtp/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/smtp/{name}", + "section": "cluster", + "summary": "update_smtp_endpoint", + "searchText": "PUT\n/cluster/notifications/endpoints/smtp/{name}\ncluster\nupdate_smtp_endpoint\nUpdate existing smtp endpoint\nname string The name of the endpoint.\nauthor string Author of the mail. Defaults to 'Proxmox VE'.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nfrom-address string `From` address for the mail\nmailto array List of email recipients\nmailto-user array List of users\nmode string Determine which encryption method shall be used for the connection. insecure starttls tls\npassword string Password for SMTP authentication\nport integer 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.\nserver string The address of the SMTP server.\nusername string Username for SMTP authentication" + }, + { + "id": "GET /cluster/notifications/endpoints/webhook", + "title": "GET /cluster/notifications/endpoints/webhook", + "method": "GET", + "path": "/cluster/notifications/endpoints/webhook", + "section": "cluster", + "summary": "get_webhook_endpoints", + "searchText": "GET\n/cluster/notifications/endpoints/webhook\ncluster\nget_webhook_endpoints\nReturns a list of all webhook endpoints" + }, + { + "id": "POST /cluster/notifications/endpoints/webhook", + "title": "POST /cluster/notifications/endpoints/webhook", + "method": "POST", + "path": "/cluster/notifications/endpoints/webhook", + "section": "cluster", + "summary": "create_webhook_endpoint", + "searchText": "POST\n/cluster/notifications/endpoints/webhook\ncluster\ncreate_webhook_endpoint\nCreate a new webhook endpoint\nmethod string HTTP method post put get\nname string The name of the endpoint.\nurl string Server URL\nbody string HTTP body, base64 encoded\ncomment string Comment\ndisable boolean Disable this target\nheader array HTTP headers to set. These have to be formatted as a property string in the format name=,value=\nsecret array Secrets to set. These have to be formatted as a property string in the format name=,value=" + }, + { + "id": "DELETE /cluster/notifications/endpoints/webhook/{name}", + "title": "DELETE /cluster/notifications/endpoints/webhook/{name}", + "method": "DELETE", + "path": "/cluster/notifications/endpoints/webhook/{name}", + "section": "cluster", + "summary": "delete_webhook_endpoint", + "searchText": "DELETE\n/cluster/notifications/endpoints/webhook/{name}\ncluster\ndelete_webhook_endpoint\nRemove webhook endpoint\nname string" + }, + { + "id": "GET /cluster/notifications/endpoints/webhook/{name}", + "title": "GET /cluster/notifications/endpoints/webhook/{name}", + "method": "GET", + "path": "/cluster/notifications/endpoints/webhook/{name}", + "section": "cluster", + "summary": "get_webhook_endpoint", + "searchText": "GET\n/cluster/notifications/endpoints/webhook/{name}\ncluster\nget_webhook_endpoint\nReturn a specific webhook endpoint\nname string Name of the endpoint." + }, + { + "id": "PUT /cluster/notifications/endpoints/webhook/{name}", + "title": "PUT /cluster/notifications/endpoints/webhook/{name}", + "method": "PUT", + "path": "/cluster/notifications/endpoints/webhook/{name}", + "section": "cluster", + "summary": "update_webhook_endpoint", + "searchText": "PUT\n/cluster/notifications/endpoints/webhook/{name}\ncluster\nupdate_webhook_endpoint\nUpdate existing webhook endpoint\nname string The name of the endpoint.\nbody string HTTP body, base64 encoded\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this target\nheader array HTTP headers to set. These have to be formatted as a property string in the format name=,value=\nmethod string HTTP method post put get\nsecret array Secrets to set. These have to be formatted as a property string in the format name=,value=\nurl string Server URL" + }, + { + "id": "GET /cluster/notifications/matcher-field-values", + "title": "GET /cluster/notifications/matcher-field-values", + "method": "GET", + "path": "/cluster/notifications/matcher-field-values", + "section": "cluster", + "summary": "get_matcher_field_values", + "searchText": "GET\n/cluster/notifications/matcher-field-values\ncluster\nget_matcher_field_values\nReturns known notification metadata fields and their known values" + }, + { + "id": "GET /cluster/notifications/matcher-fields", + "title": "GET /cluster/notifications/matcher-fields", + "method": "GET", + "path": "/cluster/notifications/matcher-fields", + "section": "cluster", + "summary": "get_matcher_fields", + "searchText": "GET\n/cluster/notifications/matcher-fields\ncluster\nget_matcher_fields\nReturns known notification metadata fields" + }, + { + "id": "GET /cluster/notifications/matchers", + "title": "GET /cluster/notifications/matchers", + "method": "GET", + "path": "/cluster/notifications/matchers", + "section": "cluster", + "summary": "get_matchers", + "searchText": "GET\n/cluster/notifications/matchers\ncluster\nget_matchers\nReturns a list of all matchers" + }, + { + "id": "POST /cluster/notifications/matchers", + "title": "POST /cluster/notifications/matchers", + "method": "POST", + "path": "/cluster/notifications/matchers", + "section": "cluster", + "summary": "create_matcher", + "searchText": "POST\n/cluster/notifications/matchers\ncluster\ncreate_matcher\nCreate a new matcher\nname string Name of the matcher.\ncomment string Comment\ndisable boolean Disable this matcher\ninvert-match boolean Invert match of the whole matcher\nmatch-calendar array Match notification timestamp\nmatch-field array Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=\nmatch-severity array Notification severities to match\nmode string Choose between 'all' and 'any' for when multiple properties are specified all any\ntarget array Targets to notify on match" + }, + { + "id": "DELETE /cluster/notifications/matchers/{name}", + "title": "DELETE /cluster/notifications/matchers/{name}", + "method": "DELETE", + "path": "/cluster/notifications/matchers/{name}", + "section": "cluster", + "summary": "delete_matcher", + "searchText": "DELETE\n/cluster/notifications/matchers/{name}\ncluster\ndelete_matcher\nRemove matcher\nname string" + }, + { + "id": "GET /cluster/notifications/matchers/{name}", + "title": "GET /cluster/notifications/matchers/{name}", + "method": "GET", + "path": "/cluster/notifications/matchers/{name}", + "section": "cluster", + "summary": "get_matcher", + "searchText": "GET\n/cluster/notifications/matchers/{name}\ncluster\nget_matcher\nReturn a specific matcher\nname string" + }, + { + "id": "PUT /cluster/notifications/matchers/{name}", + "title": "PUT /cluster/notifications/matchers/{name}", + "method": "PUT", + "path": "/cluster/notifications/matchers/{name}", + "section": "cluster", + "summary": "update_matcher", + "searchText": "PUT\n/cluster/notifications/matchers/{name}\ncluster\nupdate_matcher\nUpdate existing matcher\nname string Name of the matcher.\ncomment string Comment\ndelete array A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Disable this matcher\ninvert-match boolean Invert match of the whole matcher\nmatch-calendar array Match notification timestamp\nmatch-field array Metadata fields to match (regex or exact match). Must be in the form (regex|exact):=\nmatch-severity array Notification severities to match\nmode string Choose between 'all' and 'any' for when multiple properties are specified all any\ntarget array Targets to notify on match" + }, + { + "id": "GET /cluster/notifications/targets", + "title": "GET /cluster/notifications/targets", + "method": "GET", + "path": "/cluster/notifications/targets", + "section": "cluster", + "summary": "get_all_targets", + "searchText": "GET\n/cluster/notifications/targets\ncluster\nget_all_targets\nReturns a list of all entities that can be used as notification targets." + }, + { + "id": "POST /cluster/notifications/targets/{name}/test", + "title": "POST /cluster/notifications/targets/{name}/test", + "method": "POST", + "path": "/cluster/notifications/targets/{name}/test", + "section": "cluster", + "summary": "test_target", + "searchText": "POST\n/cluster/notifications/targets/{name}/test\ncluster\ntest_target\nSend a test notification to a provided target.\nname string Name of the target." + }, + { + "id": "GET /cluster/options", + "title": "GET /cluster/options", + "method": "GET", + "path": "/cluster/options", + "section": "cluster", + "summary": "get_options", + "searchText": "GET\n/cluster/options\ncluster\nget_options\nGet datacenter options. Without 'Sys.Audit' on '/' not all options are returned." + }, + { + "id": "PUT /cluster/options", + "title": "PUT /cluster/options", + "method": "PUT", + "path": "/cluster/options", + "section": "cluster", + "summary": "set_options", + "searchText": "PUT\n/cluster/options\ncluster\nset_options\nSet datacenter options.\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\nconsent-text string Consent text that is displayed before logging in.\nconsole string 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. applet vv html5 xtermjs\ncrs string Cluster resource scheduling settings.\ndelete string A list of settings you want to delete.\ndescription string Datacenter description. Shown in the web-interface datacenter notes panel. This is saved as comment inside the configuration file.\nemail_from string Specify email address to send notification from (default is root@$hostname)\nfencing string 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 watchdog hardware both\nha string Cluster wide HA settings.\nhttp_proxy string Specify external http proxy which is used for downloads (example: 'http://username:password@host:port/')\nkeyboard string Default keybord layout for vnc server. 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\nlanguage string Default GUI language. 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\nlocation string The location of the cluster.\nmac_prefix string 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).\nmax_workers integer Defines how many workers (per node) are maximal started on actions like 'stopall VMs' or task from the ha-manager.\nmigration string For cluster wide migration settings.\nmigration_unsecure boolean 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!\nnext-id string Control the range for the free VMID auto-selection pool.\nnotify string Cluster-wide notification settings.\nregistered-tags string 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`.\nreplication string For cluster wide replication settings.\ntag-style string Tag style options.\nu2f string u2f\nuser-tag-access string Privilege options for user-settable tags\nwebauthn string webauthn configuration" + }, + { + "id": "GET /cluster/qemu", + "title": "GET /cluster/qemu", + "method": "GET", + "path": "/cluster/qemu", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/qemu\ncluster\nindex\nCluster-wide QEMU index\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/qemu/cpu-flags", + "title": "GET /cluster/qemu/cpu-flags", + "method": "GET", + "path": "/cluster/qemu/cpu-flags", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/qemu/cpu-flags\ncluster\nindex\nList of available CPU flags. Currently only implemented for x86_64, returns an empty list for aarch64.\naccel string Acceleration type to check node compatibility for. kvm tcg\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/qemu/custom-cpu-models", + "title": "GET /cluster/qemu/custom-cpu-models", + "method": "GET", + "path": "/cluster/qemu/custom-cpu-models", + "section": "cluster", + "summary": "config", + "searchText": "GET\n/cluster/qemu/custom-cpu-models\ncluster\nconfig\nList all custom CPU model definitions visible to the user.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "POST /cluster/qemu/custom-cpu-models", + "title": "POST /cluster/qemu/custom-cpu-models", + "method": "POST", + "path": "/cluster/qemu/custom-cpu-models", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/qemu/custom-cpu-models\ncluster\ncreate\nAdd a custom CPU model definition.\ncputype string Name for the custom CPU model. The 'custom-' prefix is optional.\nreported-model string 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. 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\nflags string 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\nguest-phys-bits integer Number of physical address bits available to the guest.\nhidden boolean Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.\nhv-vendor-id string The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.\nlevel integer 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.\nphys-bits string 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.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "DELETE /cluster/qemu/custom-cpu-models/{cputype}", + "title": "DELETE /cluster/qemu/custom-cpu-models/{cputype}", + "method": "DELETE", + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\ndelete\nDelete a custom CPU model definition.\ncputype string The custom model to delete. The 'custom-' prefix is optional.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/qemu/custom-cpu-models/{cputype}", + "title": "GET /cluster/qemu/custom-cpu-models/{cputype}", + "method": "GET", + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "section": "cluster", + "summary": "info", + "searchText": "GET\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\ninfo\nRetrieve details about a specific custom CPU model.\ncputype string Name of the CPU model to query. The 'custom-' prefix is optional.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "PUT /cluster/qemu/custom-cpu-models/{cputype}", + "title": "PUT /cluster/qemu/custom-cpu-models/{cputype}", + "method": "PUT", + "path": "/cluster/qemu/custom-cpu-models/{cputype}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/qemu/custom-cpu-models/{cputype}\ncluster\nupdate\nUpdate a custom CPU model definition.\ncputype string Name for the custom CPU model. The 'custom-' prefix is optional.\ndelete string A list of properties to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nflags string 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\nguest-phys-bits integer Number of physical address bits available to the guest.\nhidden boolean Do not identify as a KVM virtual machine. Only affects vCPUs with x86-64 architecture.\nhv-vendor-id string The Hyper-V vendor ID. Some drivers or programs inside Windows guests need a specific ID.\nlevel integer 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.\nphys-bits string 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.\nreported-model string 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. 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\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /cluster/replication", + "title": "GET /cluster/replication", + "method": "GET", + "path": "/cluster/replication", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/replication\ncluster\nindex\nList replication jobs." + }, + { + "id": "POST /cluster/replication", + "title": "POST /cluster/replication", + "method": "POST", + "path": "/cluster/replication", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/replication\ncluster\ncreate\nCreate a new replication job\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\ntarget string Target node.\ntype string Section type. local\ncomment string Description.\ndisable boolean Flag to disable/deactivate the entry.\nrate number Rate limit in mbps (megabytes per second) as floating point number.\nremove_job string 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. local full\nschedule string Storage replication schedule. The format is a subset of `systemd` calendar events.\nsource string For internal use, to detect if the guest was stolen." + }, + { + "id": "DELETE /cluster/replication/{id}", + "title": "DELETE /cluster/replication/{id}", + "method": "DELETE", + "path": "/cluster/replication/{id}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/replication/{id}\ncluster\ndelete\nMark replication job for removal.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nforce boolean Will remove the jobconfig entry, but will not cleanup.\nkeep boolean Keep replicated data at target (do not remove)." + }, + { + "id": "GET /cluster/replication/{id}", + "title": "GET /cluster/replication/{id}", + "method": "GET", + "path": "/cluster/replication/{id}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/replication/{id}\ncluster\nread\nRead replication job configuration.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'." + }, + { + "id": "PUT /cluster/replication/{id}", + "title": "PUT /cluster/replication/{id}", + "method": "PUT", + "path": "/cluster/replication/{id}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/replication/{id}\ncluster\nupdate\nUpdate replication job configuration.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\ncomment string Description.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable/deactivate the entry.\nrate number Rate limit in mbps (megabytes per second) as floating point number.\nremove_job string 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. local full\nschedule string Storage replication schedule. The format is a subset of `systemd` calendar events.\nsource string For internal use, to detect if the guest was stolen." + }, + { + "id": "GET /cluster/resources", + "title": "GET /cluster/resources", + "method": "GET", + "path": "/cluster/resources", + "section": "cluster", + "summary": "resources", + "searchText": "GET\n/cluster/resources\ncluster\nresources\nResources index (cluster wide).\ntype string Resource type. vm storage node sdn" + }, + { + "id": "GET /cluster/sdn", + "title": "GET /cluster/sdn", + "method": "GET", + "path": "/cluster/sdn", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn\ncluster\nindex\nDirectory index." + }, + { + "id": "PUT /cluster/sdn", + "title": "PUT /cluster/sdn", + "method": "PUT", + "path": "/cluster/sdn", + "section": "cluster", + "summary": "reload", + "searchText": "PUT\n/cluster/sdn\ncluster\nreload\nApply sdn controller changes && reload.\nlock-token string the token for unlocking the global SDN configuration\nrelease-lock boolean When lock-token has been provided and configuration successfully committed, release the lock automatically afterwards" + }, + { + "id": "GET /cluster/sdn/controllers", + "title": "GET /cluster/sdn/controllers", + "method": "GET", + "path": "/cluster/sdn/controllers", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/controllers\ncluster\nindex\nSDN controllers index.\npending boolean Display pending config.\nrunning boolean Display running config.\ntype string Only list sdn controllers of specific type bgp evpn faucet isis" + }, + { + "id": "POST /cluster/sdn/controllers", + "title": "POST /cluster/sdn/controllers", + "method": "POST", + "path": "/cluster/sdn/controllers", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/sdn/controllers\ncluster\ncreate\nCreate a new sdn controller object.\ncontroller string The SDN controller object identifier.\ntype string Plugin type. bgp evpn faucet isis\nasn integer autonomous system number\nbgp-mode string Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. auto external internal\nbgp-multipath-as-path-relax boolean Consider different AS paths of equal length for multipath computation.\nebgp boolean Enable eBGP (remote-as external).\nebgp-multihop integer Set maximum amount of hops for eBGP peers.\nfabric string SDN fabric to use as underlay for this EVPN controller.\nisis-domain string Name of the IS-IS domain.\nisis-ifaces string Comma-separated list of interfaces where IS-IS should be active.\nisis-net string Network Entity title for this node in the IS-IS network.\nlock-token string the token for unlocking the global SDN configuration\nloopback string Name of the loopback/dummy interface that provides the Router-IP.\nnode string The cluster node name.\nnodes string List of cluster node names.\npeer-group-name string Name of the peer group for this EVPN controller\npeers string peers address list.\nroute-map-in string Route Map that should be applied for incoming routes\nroute-map-out string Route Map that should be applied for outgoing routes" + }, + { + "id": "DELETE /cluster/sdn/controllers/{controller}", + "title": "DELETE /cluster/sdn/controllers/{controller}", + "method": "DELETE", + "path": "/cluster/sdn/controllers/{controller}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/sdn/controllers/{controller}\ncluster\ndelete\nDelete sdn controller object configuration.\ncontroller string The SDN controller object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/controllers/{controller}", + "title": "GET /cluster/sdn/controllers/{controller}", + "method": "GET", + "path": "/cluster/sdn/controllers/{controller}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/sdn/controllers/{controller}\ncluster\nread\nRead sdn controller configuration.\ncontroller string The SDN controller object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/controllers/{controller}", + "title": "PUT /cluster/sdn/controllers/{controller}", + "method": "PUT", + "path": "/cluster/sdn/controllers/{controller}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/sdn/controllers/{controller}\ncluster\nupdate\nUpdate sdn controller object configuration.\ncontroller string The SDN controller object identifier.\nasn integer autonomous system number\nbgp-mode string Whether to use eBGP or iBGP. Auto mode chooses depending on BGP controller or falls back to iBGP. auto external internal\nbgp-multipath-as-path-relax boolean Consider different AS paths of equal length for multipath computation.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nebgp boolean Enable eBGP (remote-as external).\nebgp-multihop integer Set maximum amount of hops for eBGP peers.\nfabric string SDN fabric to use as underlay for this EVPN controller.\nisis-domain string Name of the IS-IS domain.\nisis-ifaces string Comma-separated list of interfaces where IS-IS should be active.\nisis-net string Network Entity title for this node in the IS-IS network.\nlock-token string the token for unlocking the global SDN configuration\nloopback string Name of the loopback/dummy interface that provides the Router-IP.\nnode string The cluster node name.\nnodes string List of cluster node names.\npeer-group-name string Name of the peer group for this EVPN controller\npeers string peers address list.\nroute-map-in string Route Map that should be applied for incoming routes\nroute-map-out string Route Map that should be applied for outgoing routes" + }, + { + "id": "GET /cluster/sdn/dns", + "title": "GET /cluster/sdn/dns", + "method": "GET", + "path": "/cluster/sdn/dns", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/dns\ncluster\nindex\nSDN dns index.\ntype string Only list sdn dns of specific type powerdns" + }, + { + "id": "POST /cluster/sdn/dns", + "title": "POST /cluster/sdn/dns", + "method": "POST", + "path": "/cluster/sdn/dns", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/sdn/dns\ncluster\ncreate\nCreate a new sdn dns object.\ndns string The SDN dns object identifier.\nkey string\ntype string Plugin type. powerdns\nurl string\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nreversemaskv6 integer\nreversev6mask integer\nttl integer" + }, + { + "id": "DELETE /cluster/sdn/dns/{dns}", + "title": "DELETE /cluster/sdn/dns/{dns}", + "method": "DELETE", + "path": "/cluster/sdn/dns/{dns}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/sdn/dns/{dns}\ncluster\ndelete\nDelete sdn dns object configuration.\ndns string The SDN dns object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/dns/{dns}", + "title": "GET /cluster/sdn/dns/{dns}", + "method": "GET", + "path": "/cluster/sdn/dns/{dns}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/sdn/dns/{dns}\ncluster\nread\nRead sdn dns configuration.\ndns string The SDN dns object identifier." + }, + { + "id": "PUT /cluster/sdn/dns/{dns}", + "title": "PUT /cluster/sdn/dns/{dns}", + "method": "PUT", + "path": "/cluster/sdn/dns/{dns}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/sdn/dns/{dns}\ncluster\nupdate\nUpdate sdn dns object configuration.\ndns string The SDN dns object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfingerprint string Certificate SHA 256 fingerprint.\nkey string\nlock-token string the token for unlocking the global SDN configuration\nreversemaskv6 integer\nttl integer\nurl string" + }, + { + "id": "GET /cluster/sdn/dry-run", + "title": "GET /cluster/sdn/dry-run", + "method": "GET", + "path": "/cluster/sdn/dry-run", + "section": "cluster", + "summary": "dry-run", + "searchText": "GET\n/cluster/sdn/dry-run\ncluster\ndry-run\nDry-run the SDN apply action and return the difference between the current configuration and the pending configuration\nnode string The cluster node name." + }, + { + "id": "GET /cluster/sdn/fabrics", + "title": "GET /cluster/sdn/fabrics", + "method": "GET", + "path": "/cluster/sdn/fabrics", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/fabrics\ncluster\nindex\nSDN Fabrics Index" + }, + { + "id": "GET /cluster/sdn/fabrics/all", + "title": "GET /cluster/sdn/fabrics/all", + "method": "GET", + "path": "/cluster/sdn/fabrics/all", + "section": "cluster", + "summary": "list_all", + "searchText": "GET\n/cluster/sdn/fabrics/all\ncluster\nlist_all\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "GET /cluster/sdn/fabrics/fabric", + "title": "GET /cluster/sdn/fabrics/fabric", + "method": "GET", + "path": "/cluster/sdn/fabrics/fabric", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/fabrics/fabric\ncluster\nindex\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/fabrics/fabric", + "title": "POST /cluster/sdn/fabrics/fabric", + "method": "POST", + "path": "/cluster/sdn/fabrics/fabric", + "section": "cluster", + "summary": "add_fabric", + "searchText": "POST\n/cluster/sdn/fabrics/fabric\ncluster\nadd_fabric\nAdd a fabric\nid string Identifier for SDN fabrics\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nredistribute array\narea string OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.\ncsnp_interval number The csnp_interval property for Openfabric\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nhello_interval number The hello_interval property for Openfabric\nip_prefix string The IP prefix for Node IPs\nip6_prefix string The IP prefix for Node IPs\nlock-token string the token for unlocking the global SDN configuration\npersistent_keepalive number 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\nroute_filter string A prefix list that should be used for filtering routes that are to be installed into the kernel routing table" + }, + { + "id": "DELETE /cluster/sdn/fabrics/fabric/{id}", + "title": "DELETE /cluster/sdn/fabrics/fabric/{id}", + "method": "DELETE", + "path": "/cluster/sdn/fabrics/fabric/{id}", + "section": "cluster", + "summary": "delete_fabric", + "searchText": "DELETE\n/cluster/sdn/fabrics/fabric/{id}\ncluster\ndelete_fabric\nAdd a fabric\nid string Identifier for SDN fabrics" + }, + { + "id": "GET /cluster/sdn/fabrics/fabric/{id}", + "title": "GET /cluster/sdn/fabrics/fabric/{id}", + "method": "GET", + "path": "/cluster/sdn/fabrics/fabric/{id}", + "section": "cluster", + "summary": "get_fabric", + "searchText": "GET\n/cluster/sdn/fabrics/fabric/{id}\ncluster\nget_fabric\nUpdate a fabric\nid string Identifier for SDN fabrics" + }, + { + "id": "PUT /cluster/sdn/fabrics/fabric/{id}", + "title": "PUT /cluster/sdn/fabrics/fabric/{id}", + "method": "PUT", + "path": "/cluster/sdn/fabrics/fabric/{id}", + "section": "cluster", + "summary": "update_fabric", + "searchText": "PUT\n/cluster/sdn/fabrics/fabric/{id}\ncluster\nupdate_fabric\nUpdate a fabric\nid string Identifier for SDN fabrics\ndelete array\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nredistribute array\narea string OSPF area. Either a IPv4 address or a 32-bit number. Gets validated in rust.\ncsnp_interval number The csnp_interval property for Openfabric\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nhello_interval number The hello_interval property for Openfabric\nip_prefix string The IP prefix for Node IPs\nip6_prefix string The IP prefix for Node IPs\nlock-token string the token for unlocking the global SDN configuration\npersistent_keepalive number 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\nroute_filter string A prefix list that should be used for filtering routes that are to be installed into the kernel routing table" + }, + { + "id": "GET /cluster/sdn/fabrics/node", + "title": "GET /cluster/sdn/fabrics/node", + "method": "GET", + "path": "/cluster/sdn/fabrics/node", + "section": "cluster", + "summary": "list_nodes", + "searchText": "GET\n/cluster/sdn/fabrics/node\ncluster\nlist_nodes\nSDN Fabrics Index\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "GET /cluster/sdn/fabrics/node/{fabric_id}", + "title": "GET /cluster/sdn/fabrics/node/{fabric_id}", + "method": "GET", + "path": "/cluster/sdn/fabrics/node/{fabric_id}", + "section": "cluster", + "summary": "list_nodes_fabric", + "searchText": "GET\n/cluster/sdn/fabrics/node/{fabric_id}\ncluster\nlist_nodes_fabric\nSDN Fabrics Index\nfabric_id string Identifier for SDN fabrics\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/fabrics/node/{fabric_id}", + "title": "POST /cluster/sdn/fabrics/node/{fabric_id}", + "method": "POST", + "path": "/cluster/sdn/fabrics/node/{fabric_id}", + "section": "cluster", + "summary": "add_node", + "searchText": "POST\n/cluster/sdn/fabrics/node/{fabric_id}\ncluster\nadd_node\nAdd a node\nfabric_id string Identifier for SDN fabrics\ninterfaces array\nnode_id string Identifier for nodes in an SDN fabric\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nallowed_ips array A list of IPs that are routable via this node in the WireGuard fabric.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nendpoint string The endpoint used for connecting to this node.\nip string IPv4 address for this node\nip6 string IPv6 address for this node\nlock-token string the token for unlocking the global SDN configuration\npeers array\npublic_key string The public key for the external node.\nrole string The role of this node in the WireGuard fabric. internal external" + }, + { + "id": "DELETE /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "title": "DELETE /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "method": "DELETE", + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "section": "cluster", + "summary": "delete_node", + "searchText": "DELETE\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\ndelete_node\nAdd a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric" + }, + { + "id": "GET /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "title": "GET /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "method": "GET", + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "section": "cluster", + "summary": "get_node", + "searchText": "GET\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\nget_node\nGet a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric" + }, + { + "id": "PUT /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "title": "PUT /cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "method": "PUT", + "path": "/cluster/sdn/fabrics/node/{fabric_id}/{node_id}", + "section": "cluster", + "summary": "update_node", + "searchText": "PUT\n/cluster/sdn/fabrics/node/{fabric_id}/{node_id}\ncluster\nupdate_node\nUpdate a node\nfabric_id string Identifier for SDN fabrics\nnode_id string Identifier for nodes in an SDN fabric\ndelete array\ninterfaces array\nprotocol string Type of configuration entry in an SDN Fabric section config openfabric ospf wireguard bgp\nallowed_ips array A list of IPs that are routable via this node in the WireGuard fabric.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nendpoint string The endpoint used for connecting to this node.\nip string IPv4 address for this node\nip6 string IPv6 address for this node\nlock-token string the token for unlocking the global SDN configuration\npeers array\npublic_key string The public key for the external node.\nrole string The role of this node in the WireGuard fabric. internal external" + }, + { + "id": "GET /cluster/sdn/ipams", + "title": "GET /cluster/sdn/ipams", + "method": "GET", + "path": "/cluster/sdn/ipams", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/ipams\ncluster\nindex\nSDN ipams index.\ntype string Only list sdn ipams of specific type netbox phpipam pve" + }, + { + "id": "POST /cluster/sdn/ipams", + "title": "POST /cluster/sdn/ipams", + "method": "POST", + "path": "/cluster/sdn/ipams", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/sdn/ipams\ncluster\ncreate\nCreate a new sdn ipam object.\nipam string The SDN ipam object identifier.\ntype string Plugin type. netbox phpipam pve\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nsection integer\ntoken string\nurl string" + }, + { + "id": "DELETE /cluster/sdn/ipams/{ipam}", + "title": "DELETE /cluster/sdn/ipams/{ipam}", + "method": "DELETE", + "path": "/cluster/sdn/ipams/{ipam}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/sdn/ipams/{ipam}\ncluster\ndelete\nDelete sdn ipam object configuration.\nipam string The SDN ipam object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/ipams/{ipam}", + "title": "GET /cluster/sdn/ipams/{ipam}", + "method": "GET", + "path": "/cluster/sdn/ipams/{ipam}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/sdn/ipams/{ipam}\ncluster\nread\nRead sdn ipam configuration.\nipam string The SDN ipam object identifier." + }, + { + "id": "PUT /cluster/sdn/ipams/{ipam}", + "title": "PUT /cluster/sdn/ipams/{ipam}", + "method": "PUT", + "path": "/cluster/sdn/ipams/{ipam}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/sdn/ipams/{ipam}\ncluster\nupdate\nUpdate sdn ipam object configuration.\nipam string The SDN ipam object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nfingerprint string Certificate SHA 256 fingerprint.\nlock-token string the token for unlocking the global SDN configuration\nsection integer\ntoken string\nurl string" + }, + { + "id": "GET /cluster/sdn/ipams/{ipam}/status", + "title": "GET /cluster/sdn/ipams/{ipam}/status", + "method": "GET", + "path": "/cluster/sdn/ipams/{ipam}/status", + "section": "cluster", + "summary": "ipamindex", + "searchText": "GET\n/cluster/sdn/ipams/{ipam}/status\ncluster\nipamindex\nList PVE IPAM Entries\nipam string The SDN ipam object identifier." + }, + { + "id": "DELETE /cluster/sdn/lock", + "title": "DELETE /cluster/sdn/lock", + "method": "DELETE", + "path": "/cluster/sdn/lock", + "section": "cluster", + "summary": "release_lock", + "searchText": "DELETE\n/cluster/sdn/lock\ncluster\nrelease_lock\nRelease global lock for SDN configuration\nforce boolean if true, allow releasing lock without providing the token\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "POST /cluster/sdn/lock", + "title": "POST /cluster/sdn/lock", + "method": "POST", + "path": "/cluster/sdn/lock", + "section": "cluster", + "summary": "lock", + "searchText": "POST\n/cluster/sdn/lock\ncluster\nlock\nAcquire global lock for SDN configuration\nallow-pending boolean if true, allow acquiring lock even though there are pending changes" + }, + { + "id": "GET /cluster/sdn/prefix-lists", + "title": "GET /cluster/sdn/prefix-lists", + "method": "GET", + "path": "/cluster/sdn/prefix-lists", + "section": "cluster", + "summary": "list_prefix_lists", + "searchText": "GET\n/cluster/sdn/prefix-lists\ncluster\nlist_prefix_lists\nList Prefix Lists\npending boolean Display pending config.\nrunning boolean Display running config.\nverbose boolean If 0, only returns id - otherwise returns all properties." + }, + { + "id": "POST /cluster/sdn/prefix-lists", + "title": "POST /cluster/sdn/prefix-lists", + "method": "POST", + "path": "/cluster/sdn/prefix-lists", + "section": "cluster", + "summary": "create_prefix_list_entry", + "searchText": "POST\n/cluster/sdn/prefix-lists\ncluster\ncreate_prefix_list_entry\nCreate Prefix List\nid string The SDN prefix list identifier\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nentries array\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "DELETE /cluster/sdn/prefix-lists/{id}", + "title": "DELETE /cluster/sdn/prefix-lists/{id}", + "method": "DELETE", + "path": "/cluster/sdn/prefix-lists/{id}", + "section": "cluster", + "summary": "delete_prefix_list", + "searchText": "DELETE\n/cluster/sdn/prefix-lists/{id}\ncluster\ndelete_prefix_list\nDelete Prefix List\nid string The SDN prefix list identifier\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/prefix-lists/{id}", + "title": "GET /cluster/sdn/prefix-lists/{id}", + "method": "GET", + "path": "/cluster/sdn/prefix-lists/{id}", + "section": "cluster", + "summary": "get_prefix_list", + "searchText": "GET\n/cluster/sdn/prefix-lists/{id}\ncluster\nget_prefix_list\nGet Prefix List\nid string The SDN prefix list identifier" + }, + { + "id": "PUT /cluster/sdn/prefix-lists/{id}", + "title": "PUT /cluster/sdn/prefix-lists/{id}", + "method": "PUT", + "path": "/cluster/sdn/prefix-lists/{id}", + "section": "cluster", + "summary": "update_prefix_list", + "searchText": "PUT\n/cluster/sdn/prefix-lists/{id}\ncluster\nupdate_prefix_list\nUpdate Prefix List\nid string The SDN prefix list identifier\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nentries array\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/prefix-lists/{id}/entries", + "title": "GET /cluster/sdn/prefix-lists/{id}/entries", + "method": "GET", + "path": "/cluster/sdn/prefix-lists/{id}/entries", + "section": "cluster", + "summary": "get_prefix_list_entries", + "searchText": "GET\n/cluster/sdn/prefix-lists/{id}/entries\ncluster\nget_prefix_list_entries\nList Prefix List Entries\nid string The SDN prefix list identifier" + }, + { + "id": "POST /cluster/sdn/prefix-lists/{id}/entries", + "title": "POST /cluster/sdn/prefix-lists/{id}/entries", + "method": "POST", + "path": "/cluster/sdn/prefix-lists/{id}/entries", + "section": "cluster", + "summary": "create_prefix_list_entry", + "searchText": "POST\n/cluster/sdn/prefix-lists/{id}/entries\ncluster\ncreate_prefix_list_entry\nCreate Prefix List Entry\nid string The SDN prefix list identifier\naction string permit deny\nprefix string\nge integer\nle integer\nlock-token string the token for unlocking the global SDN configuration\nseq integer" + }, + { + "id": "DELETE /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "title": "DELETE /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "method": "DELETE", + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "section": "cluster", + "summary": "delete_prefix_list_entry", + "searchText": "DELETE\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\ndelete_prefix_list_entry\nDelete Prefix List Entry\nid string The SDN prefix list identifier\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "title": "GET /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "method": "GET", + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "section": "cluster", + "summary": "get_prefix_list_entry", + "searchText": "GET\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\nget_prefix_list_entry\nGet Prefix List Entry\nid string The SDN prefix list identifier" + }, + { + "id": "PUT /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "title": "PUT /cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "method": "PUT", + "path": "/cluster/sdn/prefix-lists/{id}/entries/{url_seq}", + "section": "cluster", + "summary": "update_prefix_list_entry", + "searchText": "PUT\n/cluster/sdn/prefix-lists/{id}/entries/{url_seq}\ncluster\nupdate_prefix_list_entry\nUpdate Prefix List Entry\naction string permit deny\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nge integer\nle integer\nlock-token string the token for unlocking the global SDN configuration\nprefix string\nseq integer" + }, + { + "id": "POST /cluster/sdn/rollback", + "title": "POST /cluster/sdn/rollback", + "method": "POST", + "path": "/cluster/sdn/rollback", + "section": "cluster", + "summary": "rollback", + "searchText": "POST\n/cluster/sdn/rollback\ncluster\nrollback\nRollback pending changes to SDN configuration\nlock-token string the token for unlocking the global SDN configuration\nrelease-lock boolean When lock-token has been provided and configuration successfully rollbacked, release the lock automatically afterwards" + }, + { + "id": "GET /cluster/sdn/route-maps", + "title": "GET /cluster/sdn/route-maps", + "method": "GET", + "path": "/cluster/sdn/route-maps", + "section": "cluster", + "summary": "list_route_maps", + "searchText": "GET\n/cluster/sdn/route-maps\ncluster\nlist_route_maps\nList Route Maps\nrunning boolean Display running config." + }, + { + "id": "GET /cluster/sdn/route-maps/entries", + "title": "GET /cluster/sdn/route-maps/entries", + "method": "GET", + "path": "/cluster/sdn/route-maps/entries", + "section": "cluster", + "summary": "list_route_map_entries", + "searchText": "GET\n/cluster/sdn/route-maps/entries\ncluster\nlist_route_map_entries\nLists all route map entries.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/route-maps/entries", + "title": "POST /cluster/sdn/route-maps/entries", + "method": "POST", + "path": "/cluster/sdn/route-maps/entries", + "section": "cluster", + "summary": "create_route_map_entry", + "searchText": "POST\n/cluster/sdn/route-maps/entries\ncluster\ncreate_route_map_entry\nCreate Route Map entry\naction string Matching policy of a route map entry. permit deny\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\ncall string The SDN route map identifier\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nexit-action string\nlock-token string the token for unlocking the global SDN configuration\nmatch array\nset array" + }, + { + "id": "GET /cluster/sdn/route-maps/entries/{route-map-id}", + "title": "GET /cluster/sdn/route-maps/entries/{route-map-id}", + "method": "GET", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}", + "section": "cluster", + "summary": "list_route_map_entries_for_route_map", + "searchText": "GET\n/cluster/sdn/route-maps/entries/{route-map-id}\ncluster\nlist_route_map_entries_for_route_map\nList all entries for a given Route Map\nroute-map-id string The SDN route map identifier\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "DELETE /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "title": "DELETE /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "method": "DELETE", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "section": "cluster", + "summary": "delete_route_map_entry", + "searchText": "DELETE\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\ndelete_route_map_entry\nDelete Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "title": "GET /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "method": "GET", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "section": "cluster", + "summary": "get_route_map_entry", + "searchText": "GET\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\nget_route_map_entry\nGet Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier" + }, + { + "id": "PUT /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "title": "PUT /cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "method": "PUT", + "path": "/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}", + "section": "cluster", + "summary": "update_route_map_entry", + "searchText": "PUT\n/cluster/sdn/route-maps/entries/{route-map-id}/entry/{order}\ncluster\nupdate_route_map_entry\nUpdate Route Map Entry\norder integer The index of this route map entry\nroute-map-id string The SDN route map identifier\naction string Matching policy of a route map entry. permit deny\ncall string The SDN route map identifier\ndelete array\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nexit-action string\nlock-token string the token for unlocking the global SDN configuration\nmatch array\nset array" + }, + { + "id": "GET /cluster/sdn/vnets", + "title": "GET /cluster/sdn/vnets", + "method": "GET", + "path": "/cluster/sdn/vnets", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/vnets\ncluster\nindex\nSDN vnets index.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/vnets", + "title": "POST /cluster/sdn/vnets", + "method": "POST", + "path": "/cluster/sdn/vnets", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/sdn/vnets\ncluster\ncreate\nCreate a new sdn vnet object.\nvnet string The SDN vnet object identifier.\nzone string Name of the zone this VNet belongs to.\nalias string Alias name of the VNet.\nisolate-ports boolean If true, sets the isolated property for all interfaces on the bridge of this VNet.\nlock-token string the token for unlocking the global SDN configuration\ntag integer VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).\ntype string Type of the VNet. vnet\nvlanaware boolean Allow VLANs to pass through this vnet." + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}", + "title": "DELETE /cluster/sdn/vnets/{vnet}", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}\ncluster\ndelete\nDelete sdn vnet object configuration.\nvnet string The SDN vnet object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}", + "title": "GET /cluster/sdn/vnets/{vnet}", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/sdn/vnets/{vnet}\ncluster\nread\nRead sdn vnet configuration.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}", + "title": "PUT /cluster/sdn/vnets/{vnet}", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}\ncluster\nupdate\nUpdate sdn vnet object configuration.\nvnet string The SDN vnet object identifier.\nalias string Alias name of the VNet.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nisolate-ports boolean If true, sets the isolated property for all interfaces on the bridge of this VNet.\nlock-token string the token for unlocking the global SDN configuration\ntag integer VLAN Tag (for VLAN or QinQ zones) or VXLAN VNI (for VXLAN or EVPN zones).\nvlanaware boolean Allow VLANs to pass through this vnet.\nzone string Name of the zone this VNet belongs to." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall", + "title": "GET /cluster/sdn/vnets/{vnet}/firewall", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall\ncluster\nindex\nDirectory index.\nvnet string The SDN vnet object identifier." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall/options", + "title": "GET /cluster/sdn/vnets/{vnet}/firewall/options", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "section": "cluster", + "summary": "get_options", + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall/options\ncluster\nget_options\nGet vnet firewall options.\nvnet string The SDN vnet object identifier." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/firewall/options", + "title": "PUT /cluster/sdn/vnets/{vnet}/firewall/options", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/firewall/options", + "section": "cluster", + "summary": "set_options", + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/firewall/options\ncluster\nset_options\nSet Firewall options.\nvnet string The SDN vnet object identifier.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nlog_level_forward string Log level for forwarded traffic. emerg alert crit err warning notice info debug nolog\npolicy_forward string Forward policy. ACCEPT DROP" + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall/rules", + "title": "GET /cluster/sdn/vnets/{vnet}/firewall/rules", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "section": "cluster", + "summary": "get_rules", + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall/rules\ncluster\nget_rules\nList rules.\nvnet string The SDN vnet object identifier." + }, + { + "id": "POST /cluster/sdn/vnets/{vnet}/firewall/rules", + "title": "POST /cluster/sdn/vnets/{vnet}/firewall/rules", + "method": "POST", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules", + "section": "cluster", + "summary": "create_rule", + "searchText": "POST\n/cluster/sdn/vnets/{vnet}/firewall/rules\ncluster\ncreate_rule\nCreate new rule.\nvnet string The SDN vnet object identifier.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "title": "DELETE /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "section": "cluster", + "summary": "delete_rule", + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\ndelete_rule\nDelete rule.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "title": "GET /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "section": "cluster", + "summary": "get_rule", + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\nget_rule\nGet single rule data.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position ." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "title": "PUT /cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}", + "section": "cluster", + "summary": "update_rule", + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/firewall/rules/{pos}\ncluster\nupdate_rule\nModify rule data.\nvnet string The SDN vnet object identifier.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}/ips", + "title": "DELETE /cluster/sdn/vnets/{vnet}/ips", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}/ips", + "section": "cluster", + "summary": "ipdelete", + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipdelete\nDelete IP Mappings in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to delete\nzone string The SDN zone object identifier.\nmac string Unicast MAC address." + }, + { + "id": "POST /cluster/sdn/vnets/{vnet}/ips", + "title": "POST /cluster/sdn/vnets/{vnet}/ips", + "method": "POST", + "path": "/cluster/sdn/vnets/{vnet}/ips", + "section": "cluster", + "summary": "ipcreate", + "searchText": "POST\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipcreate\nCreate IP Mapping in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to associate with the given MAC address\nzone string The SDN zone object identifier.\nmac string Unicast MAC address." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/ips", + "title": "PUT /cluster/sdn/vnets/{vnet}/ips", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/ips", + "section": "cluster", + "summary": "ipupdate", + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/ips\ncluster\nipupdate\nUpdate IP Mapping in a VNet\nvnet string The SDN vnet object identifier.\nip string The IP address to associate with the given MAC address\nzone string The SDN zone object identifier.\nmac string Unicast MAC address.\nvmid integer The (unique) ID of the VM." + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/subnets", + "title": "GET /cluster/sdn/vnets/{vnet}/subnets", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/subnets\ncluster\nindex\nSDN subnets index.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "POST /cluster/sdn/vnets/{vnet}/subnets", + "title": "POST /cluster/sdn/vnets/{vnet}/subnets", + "method": "POST", + "path": "/cluster/sdn/vnets/{vnet}/subnets", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/sdn/vnets/{vnet}/subnets\ncluster\ncreate\nCreate a new sdn subnet object.\nvnet string associated vnet\nsubnet string The SDN subnet object identifier.\ntype string subnet\ndhcp-dns-server string IP address for the DNS server\ndhcp-range array A list of DHCP ranges for this subnet\ndnszoneprefix string dns domain zone prefix ex: 'adm' -> .adm.mydomain.com\ngateway string Subnet Gateway: Will be assign on vnet for layer3 zones\nlock-token string the token for unlocking the global SDN configuration\nsnat boolean enable masquerade for this subnet if pve-firewall" + }, + { + "id": "DELETE /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "title": "DELETE /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "method": "DELETE", + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\ndelete\nDelete sdn subnet object configuration.\nsubnet string The SDN subnet object identifier.\nvnet string The SDN vnet object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "title": "GET /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "method": "GET", + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\nread\nRead sdn subnet configuration.\nsubnet string The SDN subnet object identifier.\nvnet string The SDN vnet object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "title": "PUT /cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "method": "PUT", + "path": "/cluster/sdn/vnets/{vnet}/subnets/{subnet}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/sdn/vnets/{vnet}/subnets/{subnet}\ncluster\nupdate\nUpdate sdn subnet object configuration.\nsubnet string The SDN subnet object identifier.\nvnet string associated vnet\ndelete string A list of settings you want to delete.\ndhcp-dns-server string IP address for the DNS server\ndhcp-range array A list of DHCP ranges for this subnet\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndnszoneprefix string dns domain zone prefix ex: 'adm' -> .adm.mydomain.com\ngateway string Subnet Gateway: Will be assign on vnet for layer3 zones\nlock-token string the token for unlocking the global SDN configuration\nsnat boolean enable masquerade for this subnet if pve-firewall" + }, + { + "id": "GET /cluster/sdn/zones", + "title": "GET /cluster/sdn/zones", + "method": "GET", + "path": "/cluster/sdn/zones", + "section": "cluster", + "summary": "index", + "searchText": "GET\n/cluster/sdn/zones\ncluster\nindex\nSDN zones index.\npending boolean Display pending config.\nrunning boolean Display running config.\ntype string Only list SDN zones of specific type evpn faucet qinq simple vlan vxlan" + }, + { + "id": "POST /cluster/sdn/zones", + "title": "POST /cluster/sdn/zones", + "method": "POST", + "path": "/cluster/sdn/zones", + "section": "cluster", + "summary": "create", + "searchText": "POST\n/cluster/sdn/zones\ncluster\ncreate\nCreate a new sdn zone object.\ntype string Plugin type. evpn faucet qinq simple vlan vxlan\nzone string The SDN zone object identifier.\nadvertise-subnets boolean Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).\nbridge string The bridge for which VLANs should be managed.\nbridge-disable-mac-learning boolean Disable auto mac learning.\ncontroller string Controller for this zone.\ndhcp string Type of the DHCP backend for this zone dnsmasq\ndisable-arp-nd-suppression boolean Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.\ndns string dns api server\ndnszone string dns domain zone ex: mydomain.com\ndp-id integer Faucet dataplane id\nexitnodes string List of cluster node names.\nexitnodes-local-routing boolean Allow exitnodes to connect to EVPN guests.\nexitnodes-primary string Force traffic through this exitnode first.\nfabric string SDN fabric to use as underlay for this VXLAN zone.\nipam string use a specific ipam\nlock-token string the token for unlocking the global SDN configuration\nmac string Anycast logical router mac address.\nmtu integer MTU of the zone, will be used for the created VNet bridges.\nnodes string List of cluster node names.\npeers string Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.\nreversedns string reverse dns api server\nrt-import string List of Route Targets that should be imported into the VRF of the zone.\nsecondary-controllers array Additional controllers.\ntag integer Service-VLAN Tag (outer VLAN)\nvlan-protocol string Which VLAN protocol should be used for the creation of the QinQ zone. 802.1q 802.1ad\nvrf-vxlan integer VNI for the zone VRF.\nvxlan-port integer UDP port that should be used for the VXLAN tunnel (default 4789)." + }, + { + "id": "DELETE /cluster/sdn/zones/{zone}", + "title": "DELETE /cluster/sdn/zones/{zone}", + "method": "DELETE", + "path": "/cluster/sdn/zones/{zone}", + "section": "cluster", + "summary": "delete", + "searchText": "DELETE\n/cluster/sdn/zones/{zone}\ncluster\ndelete\nDelete sdn zone object configuration.\nzone string The SDN zone object identifier.\nlock-token string the token for unlocking the global SDN configuration" + }, + { + "id": "GET /cluster/sdn/zones/{zone}", + "title": "GET /cluster/sdn/zones/{zone}", + "method": "GET", + "path": "/cluster/sdn/zones/{zone}", + "section": "cluster", + "summary": "read", + "searchText": "GET\n/cluster/sdn/zones/{zone}\ncluster\nread\nRead sdn zone configuration.\nzone string The SDN zone object identifier.\npending boolean Display pending config.\nrunning boolean Display running config." + }, + { + "id": "PUT /cluster/sdn/zones/{zone}", + "title": "PUT /cluster/sdn/zones/{zone}", + "method": "PUT", + "path": "/cluster/sdn/zones/{zone}", + "section": "cluster", + "summary": "update", + "searchText": "PUT\n/cluster/sdn/zones/{zone}\ncluster\nupdate\nUpdate sdn zone object configuration.\nzone string The SDN zone object identifier.\nadvertise-subnets boolean Advertise IP prefixes (Type-5 routes) instead of MAC/IP pairs (Type-2 routes).\nbridge string The bridge for which VLANs should be managed.\nbridge-disable-mac-learning boolean Disable auto mac learning.\ncontroller string Controller for this zone.\ndelete string A list of settings you want to delete.\ndhcp string Type of the DHCP backend for this zone dnsmasq\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable-arp-nd-suppression boolean Suppress IPv4 ARP && IPv6 Neighbour Discovery messages.\ndns string dns api server\ndnszone string dns domain zone ex: mydomain.com\ndp-id integer Faucet dataplane id\nexitnodes string List of cluster node names.\nexitnodes-local-routing boolean Allow exitnodes to connect to EVPN guests.\nexitnodes-primary string Force traffic through this exitnode first.\nfabric string SDN fabric to use as underlay for this VXLAN zone.\nipam string use a specific ipam\nlock-token string the token for unlocking the global SDN configuration\nmac string Anycast logical router mac address.\nmtu integer MTU of the zone, will be used for the created VNet bridges.\nnodes string List of cluster node names.\npeers string Comma-separated list of peers, that are part of the VXLAN zone. Usually the IPs of the nodes.\nreversedns string reverse dns api server\nrt-import string List of Route Targets that should be imported into the VRF of the zone.\nsecondary-controllers array Additional controllers.\ntag integer Service-VLAN Tag (outer VLAN)\nvlan-protocol string Which VLAN protocol should be used for the creation of the QinQ zone. 802.1q 802.1ad\nvrf-vxlan integer VNI for the zone VRF.\nvxlan-port integer UDP port that should be used for the VXLAN tunnel (default 4789)." + }, + { + "id": "GET /cluster/status", + "title": "GET /cluster/status", + "method": "GET", + "path": "/cluster/status", + "section": "cluster", + "summary": "get_status", + "searchText": "GET\n/cluster/status\ncluster\nget_status\nGet cluster status information." + }, + { + "id": "GET /cluster/tasks", + "title": "GET /cluster/tasks", + "method": "GET", + "path": "/cluster/tasks", + "section": "cluster", + "summary": "tasks", + "searchText": "GET\n/cluster/tasks\ncluster\ntasks\nList recent tasks (cluster wide)." + }, + { + "id": "GET /nodes", + "title": "GET /nodes", + "method": "GET", + "path": "/nodes", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes\nnodes\nindex\nCluster node index." + }, + { + "id": "GET /nodes/{node}", + "title": "GET /nodes/{node}", + "method": "GET", + "path": "/nodes/{node}", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}\nnodes\nindex\nNode index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/aplinfo", + "title": "GET /nodes/{node}/aplinfo", + "method": "GET", + "path": "/nodes/{node}/aplinfo", + "section": "nodes", + "summary": "aplinfo", + "searchText": "GET\n/nodes/{node}/aplinfo\nnodes\naplinfo\nGet list of appliances.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/aplinfo", + "title": "POST /nodes/{node}/aplinfo", + "method": "POST", + "path": "/nodes/{node}/aplinfo", + "section": "nodes", + "summary": "apl_download", + "searchText": "POST\n/nodes/{node}/aplinfo\nnodes\napl_download\nDownload appliance templates.\nnode string The cluster node name.\nstorage string The storage where the template will be stored\ntemplate string The template which will downloaded" + }, + { + "id": "GET /nodes/{node}/apt", + "title": "GET /nodes/{node}/apt", + "method": "GET", + "path": "/nodes/{node}/apt", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/apt\nnodes\nindex\nDirectory index for apt (Advanced Package Tool).\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/apt/changelog", + "title": "GET /nodes/{node}/apt/changelog", + "method": "GET", + "path": "/nodes/{node}/apt/changelog", + "section": "nodes", + "summary": "changelog", + "searchText": "GET\n/nodes/{node}/apt/changelog\nnodes\nchangelog\nGet package changelogs.\nnode string The cluster node name.\nname string Package name.\nversion string Package version." + }, + { + "id": "GET /nodes/{node}/apt/repositories", + "title": "GET /nodes/{node}/apt/repositories", + "method": "GET", + "path": "/nodes/{node}/apt/repositories", + "section": "nodes", + "summary": "repositories", + "searchText": "GET\n/nodes/{node}/apt/repositories\nnodes\nrepositories\nGet APT repository information.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/apt/repositories", + "title": "POST /nodes/{node}/apt/repositories", + "method": "POST", + "path": "/nodes/{node}/apt/repositories", + "section": "nodes", + "summary": "change_repository", + "searchText": "POST\n/nodes/{node}/apt/repositories\nnodes\nchange_repository\nChange the properties of a repository. Currently only allows enabling/disabling.\nnode string The cluster node name.\nindex integer Index within the file (starting from 0).\npath string Path to the containing file.\ndigest string Digest to detect modifications.\nenabled boolean Whether the repository should be enabled or not." + }, + { + "id": "PUT /nodes/{node}/apt/repositories", + "title": "PUT /nodes/{node}/apt/repositories", + "method": "PUT", + "path": "/nodes/{node}/apt/repositories", + "section": "nodes", + "summary": "add_repository", + "searchText": "PUT\n/nodes/{node}/apt/repositories\nnodes\nadd_repository\nAdd a standard repository to the configuration\nnode string The cluster node name.\nhandle string Handle that identifies a repository.\ndigest string Digest to detect modifications." + }, + { + "id": "GET /nodes/{node}/apt/update", + "title": "GET /nodes/{node}/apt/update", + "method": "GET", + "path": "/nodes/{node}/apt/update", + "section": "nodes", + "summary": "list_updates", + "searchText": "GET\n/nodes/{node}/apt/update\nnodes\nlist_updates\nList available updates.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/apt/update", + "title": "POST /nodes/{node}/apt/update", + "method": "POST", + "path": "/nodes/{node}/apt/update", + "section": "nodes", + "summary": "update_database", + "searchText": "POST\n/nodes/{node}/apt/update\nnodes\nupdate_database\nThis is used to resynchronize the package index files from their sources (apt-get update).\nnode string The cluster node name.\nnotify boolean Send notification about new packages.\nquiet boolean Only produces output suitable for logging, omitting progress indicators." + }, + { + "id": "GET /nodes/{node}/apt/versions", + "title": "GET /nodes/{node}/apt/versions", + "method": "GET", + "path": "/nodes/{node}/apt/versions", + "section": "nodes", + "summary": "versions", + "searchText": "GET\n/nodes/{node}/apt/versions\nnodes\nversions\nGet package information for important Proxmox packages.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/capabilities", + "title": "GET /nodes/{node}/capabilities", + "method": "GET", + "path": "/nodes/{node}/capabilities", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/capabilities\nnodes\nindex\nNode capabilities index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/capabilities/qemu", + "title": "GET /nodes/{node}/capabilities/qemu", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu", + "section": "nodes", + "summary": "qemu_caps_index", + "searchText": "GET\n/nodes/{node}/capabilities/qemu\nnodes\nqemu_caps_index\nQEMU capabilities index.\nnode string The cluster node name.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/cpu", + "title": "GET /nodes/{node}/capabilities/qemu/cpu", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/cpu", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/capabilities/qemu/cpu\nnodes\nindex\nList all custom and default CPU models.\nnode string The cluster node name.\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/cpu-flags", + "title": "GET /nodes/{node}/capabilities/qemu/cpu-flags", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/cpu-flags", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/capabilities/qemu/cpu-flags\nnodes\nindex\nList of available VM-specific CPU flags. Returns an empty list for 'aarch64' as no VM-specific flags are defined for it yet.\nnode string The cluster node name.\naccel string Acceleration type to check node compatibility for. kvm tcg\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/machines", + "title": "GET /nodes/{node}/capabilities/qemu/machines", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/machines", + "section": "nodes", + "summary": "types", + "searchText": "GET\n/nodes/{node}/capabilities/qemu/machines\nnodes\ntypes\nGet available QEMU/KVM machine types.\nnode string The cluster node name.\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/capabilities/qemu/migration", + "title": "GET /nodes/{node}/capabilities/qemu/migration", + "method": "GET", + "path": "/nodes/{node}/capabilities/qemu/migration", + "section": "nodes", + "summary": "capabilities", + "searchText": "GET\n/nodes/{node}/capabilities/qemu/migration\nnodes\ncapabilities\nGet node-specific QEMU migration capabilities of the node. Requires the 'Sys.Audit' permission on '/nodes/'.\nnode string The cluster node name.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "GET /nodes/{node}/ceph", + "title": "GET /nodes/{node}/ceph", + "method": "GET", + "path": "/nodes/{node}/ceph", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/ceph\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg", + "title": "GET /nodes/{node}/ceph/cfg", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/ceph/cfg\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg/db", + "title": "GET /nodes/{node}/ceph/cfg/db", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg/db", + "section": "nodes", + "summary": "db", + "searchText": "GET\n/nodes/{node}/ceph/cfg/db\nnodes\ndb\nGet the Ceph configuration database.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg/raw", + "title": "GET /nodes/{node}/ceph/cfg/raw", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg/raw", + "section": "nodes", + "summary": "raw", + "searchText": "GET\n/nodes/{node}/ceph/cfg/raw\nnodes\nraw\nGet the Ceph configuration file.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/cfg/value", + "title": "GET /nodes/{node}/ceph/cfg/value", + "method": "GET", + "path": "/nodes/{node}/ceph/cfg/value", + "section": "nodes", + "summary": "value", + "searchText": "GET\n/nodes/{node}/ceph/cfg/value\nnodes\nvalue\nGet 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.\nnode string The cluster node name.\nconfig-keys string List of
: items separated by semicolon, comma or space." + }, + { + "id": "GET /nodes/{node}/ceph/cmd-safety", + "title": "GET /nodes/{node}/ceph/cmd-safety", + "method": "GET", + "path": "/nodes/{node}/ceph/cmd-safety", + "section": "nodes", + "summary": "cmd_safety", + "searchText": "GET\n/nodes/{node}/ceph/cmd-safety\nnodes\ncmd_safety\nHeuristical check if it is safe to perform an action.\nnode string The cluster node name.\naction string Action to check stop destroy\nid string ID of the service\nservice string Service type osd mon mds" + }, + { + "id": "GET /nodes/{node}/ceph/crush", + "title": "GET /nodes/{node}/ceph/crush", + "method": "GET", + "path": "/nodes/{node}/ceph/crush", + "section": "nodes", + "summary": "crush", + "searchText": "GET\n/nodes/{node}/ceph/crush\nnodes\ncrush\nGet OSD crush map\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/ceph/fs", + "title": "GET /nodes/{node}/ceph/fs", + "method": "GET", + "path": "/nodes/{node}/ceph/fs", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/ceph/fs\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/fs/{name}", + "title": "DELETE /nodes/{node}/ceph/fs/{name}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/fs/{name}", + "section": "nodes", + "summary": "destroyfs", + "searchText": "DELETE\n/nodes/{node}/ceph/fs/{name}\nnodes\ndestroyfs\nDestroy 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.\nname string The Ceph filesystem name.\nnode string The cluster node name.\nremove-pools boolean Remove the metadata and data pools used by this filesystem.\nremove-storages boolean Remove pveceph-managed storages configured for this filesystem." + }, + { + "id": "POST /nodes/{node}/ceph/fs/{name}", + "title": "POST /nodes/{node}/ceph/fs/{name}", + "method": "POST", + "path": "/nodes/{node}/ceph/fs/{name}", + "section": "nodes", + "summary": "createfs", + "searchText": "POST\n/nodes/{node}/ceph/fs/{name}\nnodes\ncreatefs\nCreate a Ceph filesystem\nnode string The cluster node name.\nname string The ceph filesystem name.\nadd-storage boolean Configure the created CephFS as storage for this cluster.\npg_num integer Number of placement groups for the backing data pool. The metadata pool will use a quarter of this." + }, + { + "id": "POST /nodes/{node}/ceph/init", + "title": "POST /nodes/{node}/ceph/init", + "method": "POST", + "path": "/nodes/{node}/ceph/init", + "section": "nodes", + "summary": "init", + "searchText": "POST\n/nodes/{node}/ceph/init\nnodes\ninit\nCreate 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.\nnode string The cluster node name.\ncluster-network string Declare a separate cluster network, OSDs will route heartbeat, object replication and recovery traffic over it\ndisable_cephx boolean 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!\nmin_size integer Minimum number of available replicas per object to allow I/O\nnetwork string Use specific network for all ceph related traffic\npg_bits integer Placement group bits, used to specify the default number of placement groups.\n\nDepreacted. This setting was deprecated in recent Ceph versions.\nsize integer Targeted number of replicas per object" + }, + { + "id": "GET /nodes/{node}/ceph/log", + "title": "GET /nodes/{node}/ceph/log", + "method": "GET", + "path": "/nodes/{node}/ceph/log", + "section": "nodes", + "summary": "log", + "searchText": "GET\n/nodes/{node}/ceph/log\nnodes\nlog\nRead ceph log\nnode string The cluster node name.\nlimit integer Maximum number of log lines to return. Defaults to the dump_logfile limit (typically 50) when omitted.\nstart integer Offset of the first log line to return (0-based)." + }, + { + "id": "GET /nodes/{node}/ceph/mds", + "title": "GET /nodes/{node}/ceph/mds", + "method": "GET", + "path": "/nodes/{node}/ceph/mds", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/ceph/mds\nnodes\nindex\nMDS directory index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/mds/{name}", + "title": "DELETE /nodes/{node}/ceph/mds/{name}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/mds/{name}", + "section": "nodes", + "summary": "destroymds", + "searchText": "DELETE\n/nodes/{node}/ceph/mds/{name}\nnodes\ndestroymds\nDestroy Ceph Metadata Server\nname string The name (ID) of the mds\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/mds/{name}", + "title": "POST /nodes/{node}/ceph/mds/{name}", + "method": "POST", + "path": "/nodes/{node}/ceph/mds/{name}", + "section": "nodes", + "summary": "createmds", + "searchText": "POST\n/nodes/{node}/ceph/mds/{name}\nnodes\ncreatemds\nCreate Ceph Metadata Server (MDS)\nnode string The cluster node name.\nname string The ID for the mds, when omitted the same as the nodename\nhotstandby boolean 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." + }, + { + "id": "GET /nodes/{node}/ceph/mgr", + "title": "GET /nodes/{node}/ceph/mgr", + "method": "GET", + "path": "/nodes/{node}/ceph/mgr", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/ceph/mgr\nnodes\nindex\nMGR directory index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/mgr/{id}", + "title": "DELETE /nodes/{node}/ceph/mgr/{id}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/mgr/{id}", + "section": "nodes", + "summary": "destroymgr", + "searchText": "DELETE\n/nodes/{node}/ceph/mgr/{id}\nnodes\ndestroymgr\nDestroy Ceph Manager.\nid string The ID of the manager\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/mgr/{id}", + "title": "POST /nodes/{node}/ceph/mgr/{id}", + "method": "POST", + "path": "/nodes/{node}/ceph/mgr/{id}", + "section": "nodes", + "summary": "createmgr", + "searchText": "POST\n/nodes/{node}/ceph/mgr/{id}\nnodes\ncreatemgr\nCreate Ceph Manager\nnode string The cluster node name.\nid string The ID for the manager, when omitted the same as the nodename." + }, + { + "id": "GET /nodes/{node}/ceph/mon", + "title": "GET /nodes/{node}/ceph/mon", + "method": "GET", + "path": "/nodes/{node}/ceph/mon", + "section": "nodes", + "summary": "listmon", + "searchText": "GET\n/nodes/{node}/ceph/mon\nnodes\nlistmon\nGet Ceph monitor list.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/ceph/mon/{monid}", + "title": "DELETE /nodes/{node}/ceph/mon/{monid}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/mon/{monid}", + "section": "nodes", + "summary": "destroymon", + "searchText": "DELETE\n/nodes/{node}/ceph/mon/{monid}\nnodes\ndestroymon\nDestroy 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.\nmonid string Monitor ID\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/mon/{monid}", + "title": "POST /nodes/{node}/ceph/mon/{monid}", + "method": "POST", + "path": "/nodes/{node}/ceph/mon/{monid}", + "section": "nodes", + "summary": "createmon", + "searchText": "POST\n/nodes/{node}/ceph/mon/{monid}\nnodes\ncreatemon\nCreate a Ceph Monitor. Also auto-creates a Manager for the first monitor.\nnode string The cluster node name.\nmonid string The ID for the monitor, when omitted the same as the nodename.\nmon-address string Overwrites autodetected monitor IP address(es). Must be in the public network(s) of Ceph." + }, + { + "id": "GET /nodes/{node}/ceph/osd", + "title": "GET /nodes/{node}/ceph/osd", + "method": "GET", + "path": "/nodes/{node}/ceph/osd", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/ceph/osd\nnodes\nindex\nGet Ceph osd list/tree.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/osd", + "title": "POST /nodes/{node}/ceph/osd", + "method": "POST", + "path": "/nodes/{node}/ceph/osd", + "section": "nodes", + "summary": "createosd", + "searchText": "POST\n/nodes/{node}/ceph/osd\nnodes\ncreateosd\nCreate OSD\nnode string The cluster node name.\ndev string Block device name.\ncrush-device-class string Set the device class of the OSD in crush.\ndb_dev string Block device name for block.db.\ndb_dev_size number Size in GiB for block.db.\nencrypted boolean Enables encryption of the OSD.\nosds-per-device integer OSD services per physical device. Only useful for fast NVMe devices to utilize their performance better. Mutually exclusive with 'db_dev' and 'wal_dev'.\nwal_dev string Block device name for block.wal.\nwal_dev_size number Size in GiB for block.wal." + }, + { + "id": "DELETE /nodes/{node}/ceph/osd/{osdid}", + "title": "DELETE /nodes/{node}/ceph/osd/{osdid}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/osd/{osdid}", + "section": "nodes", + "summary": "destroyosd", + "searchText": "DELETE\n/nodes/{node}/ceph/osd/{osdid}\nnodes\ndestroyosd\nDestroy OSD\nnode string The cluster node name.\nosdid integer OSD ID\ncleanup boolean 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." + }, + { + "id": "GET /nodes/{node}/ceph/osd/{osdid}", + "title": "GET /nodes/{node}/ceph/osd/{osdid}", + "method": "GET", + "path": "/nodes/{node}/ceph/osd/{osdid}", + "section": "nodes", + "summary": "osdindex", + "searchText": "GET\n/nodes/{node}/ceph/osd/{osdid}\nnodes\nosdindex\nOSD index.\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "POST /nodes/{node}/ceph/osd/{osdid}/in", + "title": "POST /nodes/{node}/ceph/osd/{osdid}/in", + "method": "POST", + "path": "/nodes/{node}/ceph/osd/{osdid}/in", + "section": "nodes", + "summary": "in", + "searchText": "POST\n/nodes/{node}/ceph/osd/{osdid}/in\nnodes\nin\nceph osd in\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "GET /nodes/{node}/ceph/osd/{osdid}/lv-info", + "title": "GET /nodes/{node}/ceph/osd/{osdid}/lv-info", + "method": "GET", + "path": "/nodes/{node}/ceph/osd/{osdid}/lv-info", + "section": "nodes", + "summary": "osdvolume", + "searchText": "GET\n/nodes/{node}/ceph/osd/{osdid}/lv-info\nnodes\nosdvolume\nGet OSD volume details\nnode string The cluster node name.\nosdid integer OSD ID\ntype string OSD device type block db wal" + }, + { + "id": "GET /nodes/{node}/ceph/osd/{osdid}/metadata", + "title": "GET /nodes/{node}/ceph/osd/{osdid}/metadata", + "method": "GET", + "path": "/nodes/{node}/ceph/osd/{osdid}/metadata", + "section": "nodes", + "summary": "osddetails", + "searchText": "GET\n/nodes/{node}/ceph/osd/{osdid}/metadata\nnodes\nosddetails\nGet OSD details\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "POST /nodes/{node}/ceph/osd/{osdid}/out", + "title": "POST /nodes/{node}/ceph/osd/{osdid}/out", + "method": "POST", + "path": "/nodes/{node}/ceph/osd/{osdid}/out", + "section": "nodes", + "summary": "out", + "searchText": "POST\n/nodes/{node}/ceph/osd/{osdid}/out\nnodes\nout\nceph osd out\nnode string The cluster node name.\nosdid integer OSD ID" + }, + { + "id": "POST /nodes/{node}/ceph/osd/{osdid}/scrub", + "title": "POST /nodes/{node}/ceph/osd/{osdid}/scrub", + "method": "POST", + "path": "/nodes/{node}/ceph/osd/{osdid}/scrub", + "section": "nodes", + "summary": "scrub", + "searchText": "POST\n/nodes/{node}/ceph/osd/{osdid}/scrub\nnodes\nscrub\nInstruct the OSD to scrub.\nnode string The cluster node name.\nosdid integer OSD ID\ndeep boolean If set, instructs a deep scrub instead of a normal one." + }, + { + "id": "GET /nodes/{node}/ceph/pool", + "title": "GET /nodes/{node}/ceph/pool", + "method": "GET", + "path": "/nodes/{node}/ceph/pool", + "section": "nodes", + "summary": "lspools", + "searchText": "GET\n/nodes/{node}/ceph/pool\nnodes\nlspools\nList all pools and their settings (which are settable by the POST/PUT endpoints).\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/pool", + "title": "POST /nodes/{node}/ceph/pool", + "method": "POST", + "path": "/nodes/{node}/ceph/pool", + "section": "nodes", + "summary": "createpool", + "searchText": "POST\n/nodes/{node}/ceph/pool\nnodes\ncreatepool\nCreate Ceph pool\nnode string The cluster node name.\nname string The name of the pool. It must be unique.\nadd_storages boolean 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).\napplication string The application of the pool. rbd cephfs rgw\ncrush_rule string The rule to use for mapping object placement in the cluster.\nerasure-coding string 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.\nmin_size integer Minimum number of replicas per object\npg_autoscale_mode string The automatic PG scaling mode of the pool. on off warn\npg_num integer Number of placement groups.\npg_num_min integer Minimal number of placement groups.\nsize integer Number of replicas per object\ntarget_size string The estimated target size of the pool for the PG autoscaler.\ntarget_size_ratio number The estimated target ratio of the pool for the PG autoscaler." + }, + { + "id": "DELETE /nodes/{node}/ceph/pool/{name}", + "title": "DELETE /nodes/{node}/ceph/pool/{name}", + "method": "DELETE", + "path": "/nodes/{node}/ceph/pool/{name}", + "section": "nodes", + "summary": "destroypool", + "searchText": "DELETE\n/nodes/{node}/ceph/pool/{name}\nnodes\ndestroypool\nDestroy pool\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\nforce boolean If true, destroys pool even if in use\nremove_ecprofile boolean Remove the erasure code profile. Defaults to true, if applicable.\nremove_storages boolean Remove all pveceph-managed storages configured for this pool" + }, + { + "id": "GET /nodes/{node}/ceph/pool/{name}", + "title": "GET /nodes/{node}/ceph/pool/{name}", + "method": "GET", + "path": "/nodes/{node}/ceph/pool/{name}", + "section": "nodes", + "summary": "poolindex", + "searchText": "GET\n/nodes/{node}/ceph/pool/{name}\nnodes\npoolindex\nPool index.\nname string The name of the pool.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/ceph/pool/{name}", + "title": "PUT /nodes/{node}/ceph/pool/{name}", + "method": "PUT", + "path": "/nodes/{node}/ceph/pool/{name}", + "section": "nodes", + "summary": "setpool", + "searchText": "PUT\n/nodes/{node}/ceph/pool/{name}\nnodes\nsetpool\nChange POOL settings\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\napplication string The application of the pool. rbd cephfs rgw\ncrush_rule string The rule to use for mapping object placement in the cluster.\nmin_size integer Minimum number of replicas per object\npg_autoscale_mode string The automatic PG scaling mode of the pool. on off warn\npg_num integer Number of placement groups.\npg_num_min integer Minimal number of placement groups.\nsize integer Number of replicas per object\ntarget_size string The estimated target size of the pool for the PG autoscaler.\ntarget_size_ratio number The estimated target ratio of the pool for the PG autoscaler." + }, + { + "id": "GET /nodes/{node}/ceph/pool/{name}/status", + "title": "GET /nodes/{node}/ceph/pool/{name}/status", + "method": "GET", + "path": "/nodes/{node}/ceph/pool/{name}/status", + "section": "nodes", + "summary": "getpool", + "searchText": "GET\n/nodes/{node}/ceph/pool/{name}/status\nnodes\ngetpool\nShow the current pool status.\nname string The name of the pool. It must be unique.\nnode string The cluster node name.\nverbose boolean If enabled, will display additional data(eg. statistics)." + }, + { + "id": "POST /nodes/{node}/ceph/restart", + "title": "POST /nodes/{node}/ceph/restart", + "method": "POST", + "path": "/nodes/{node}/ceph/restart", + "section": "nodes", + "summary": "restart", + "searchText": "POST\n/nodes/{node}/ceph/restart\nnodes\nrestart\nRestart ceph services.\nnode string The cluster node name.\nservice string Ceph service name." + }, + { + "id": "GET /nodes/{node}/ceph/rules", + "title": "GET /nodes/{node}/ceph/rules", + "method": "GET", + "path": "/nodes/{node}/ceph/rules", + "section": "nodes", + "summary": "rules", + "searchText": "GET\n/nodes/{node}/ceph/rules\nnodes\nrules\nList ceph rules.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/start", + "title": "POST /nodes/{node}/ceph/start", + "method": "POST", + "path": "/nodes/{node}/ceph/start", + "section": "nodes", + "summary": "start", + "searchText": "POST\n/nodes/{node}/ceph/start\nnodes\nstart\nStart ceph services.\nnode string The cluster node name.\nservice string Ceph service name." + }, + { + "id": "GET /nodes/{node}/ceph/status", + "title": "GET /nodes/{node}/ceph/status", + "method": "GET", + "path": "/nodes/{node}/ceph/status", + "section": "nodes", + "summary": "status", + "searchText": "GET\n/nodes/{node}/ceph/status\nnodes\nstatus\nGet 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.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/ceph/stop", + "title": "POST /nodes/{node}/ceph/stop", + "method": "POST", + "path": "/nodes/{node}/ceph/stop", + "section": "nodes", + "summary": "stop", + "searchText": "POST\n/nodes/{node}/ceph/stop\nnodes\nstop\nStop ceph services.\nnode string The cluster node name.\nservice string Ceph service name." + }, + { + "id": "GET /nodes/{node}/certificates", + "title": "GET /nodes/{node}/certificates", + "method": "GET", + "path": "/nodes/{node}/certificates", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/certificates\nnodes\nindex\nNode index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/certificates/acme", + "title": "GET /nodes/{node}/certificates/acme", + "method": "GET", + "path": "/nodes/{node}/certificates/acme", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/certificates/acme\nnodes\nindex\nACME index.\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/certificates/acme/certificate", + "title": "DELETE /nodes/{node}/certificates/acme/certificate", + "method": "DELETE", + "path": "/nodes/{node}/certificates/acme/certificate", + "section": "nodes", + "summary": "revoke_certificate", + "searchText": "DELETE\n/nodes/{node}/certificates/acme/certificate\nnodes\nrevoke_certificate\nRevoke existing certificate from CA.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/certificates/acme/certificate", + "title": "POST /nodes/{node}/certificates/acme/certificate", + "method": "POST", + "path": "/nodes/{node}/certificates/acme/certificate", + "section": "nodes", + "summary": "new_certificate", + "searchText": "POST\n/nodes/{node}/certificates/acme/certificate\nnodes\nnew_certificate\nOrder a new certificate from ACME-compatible CA.\nnode string The cluster node name.\nforce boolean Overwrite existing custom certificate." + }, + { + "id": "PUT /nodes/{node}/certificates/acme/certificate", + "title": "PUT /nodes/{node}/certificates/acme/certificate", + "method": "PUT", + "path": "/nodes/{node}/certificates/acme/certificate", + "section": "nodes", + "summary": "renew_certificate", + "searchText": "PUT\n/nodes/{node}/certificates/acme/certificate\nnodes\nrenew_certificate\nRenew existing certificate from CA.\nnode string The cluster node name.\nforce boolean Force renewal even if expiry is more than 30 days away." + }, + { + "id": "DELETE /nodes/{node}/certificates/custom", + "title": "DELETE /nodes/{node}/certificates/custom", + "method": "DELETE", + "path": "/nodes/{node}/certificates/custom", + "section": "nodes", + "summary": "remove_custom_cert", + "searchText": "DELETE\n/nodes/{node}/certificates/custom\nnodes\nremove_custom_cert\nDELETE custom certificate chain and key.\nnode string The cluster node name.\nrestart boolean Restart pveproxy." + }, + { + "id": "POST /nodes/{node}/certificates/custom", + "title": "POST /nodes/{node}/certificates/custom", + "method": "POST", + "path": "/nodes/{node}/certificates/custom", + "section": "nodes", + "summary": "upload_custom_cert", + "searchText": "POST\n/nodes/{node}/certificates/custom\nnodes\nupload_custom_cert\nUpload or update custom certificate chain and key.\nnode string The cluster node name.\ncertificates string PEM encoded certificate (chain).\nforce boolean Overwrite existing custom or ACME certificate files.\nkey string PEM encoded private key.\nrestart boolean Restart pveproxy." + }, + { + "id": "GET /nodes/{node}/certificates/info", + "title": "GET /nodes/{node}/certificates/info", + "method": "GET", + "path": "/nodes/{node}/certificates/info", + "section": "nodes", + "summary": "info", + "searchText": "GET\n/nodes/{node}/certificates/info\nnodes\ninfo\nGet information about node's certificates.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/config", + "title": "GET /nodes/{node}/config", + "method": "GET", + "path": "/nodes/{node}/config", + "section": "nodes", + "summary": "get_config", + "searchText": "GET\n/nodes/{node}/config\nnodes\nget_config\nGet node configuration options.\nnode string The cluster node name.\nproperty string Return only a specific property from the node configuration. acme acmedomain0 acmedomain1 acmedomain2 acmedomain3 acmedomain4 acmedomain5 ballooning-target description location startall-onboot-delay wakeonlan" + }, + { + "id": "PUT /nodes/{node}/config", + "title": "PUT /nodes/{node}/config", + "method": "PUT", + "path": "/nodes/{node}/config", + "section": "nodes", + "summary": "set_options", + "searchText": "PUT\n/nodes/{node}/config\nnodes\nset_options\nSet node configuration options.\nnode string The cluster node name.\nacme string Node specific ACME settings.\nacmedomain[n] string ACME domain and validation plugin\nballooning-target integer RAM usage target for ballooning (in percent of total memory)\ndelete string A list of settings you want to delete.\ndescription string Description for the Node. Shown in the web-interface node notes panel. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nlocation string The location of the node. Overrides the default from the datacenter config.\nstartall-onboot-delay integer Initial delay in seconds, before starting all the Virtual Guests with on-boot enabled.\nwakeonlan string Node specific wake on LAN settings." + }, + { + "id": "GET /nodes/{node}/disks", + "title": "GET /nodes/{node}/disks", + "method": "GET", + "path": "/nodes/{node}/disks", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/disks\nnodes\nindex\nNode index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/disks/directory", + "title": "GET /nodes/{node}/disks/directory", + "method": "GET", + "path": "/nodes/{node}/disks/directory", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/disks/directory\nnodes\nindex\nPVE Managed Directory storages.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/directory", + "title": "POST /nodes/{node}/disks/directory", + "method": "POST", + "path": "/nodes/{node}/disks/directory", + "section": "nodes", + "summary": "create", + "searchText": "POST\n/nodes/{node}/disks/directory\nnodes\ncreate\nCreate a Filesystem on an unused disk. Will be mounted under '/mnt/pve/NAME'.\nnode string The cluster node name.\ndevice string The block device you want to create the filesystem on.\nname string The storage identifier.\nadd_storage boolean Configure storage using the directory.\nfilesystem string The desired filesystem. ext4 xfs" + }, + { + "id": "DELETE /nodes/{node}/disks/directory/{name}", + "title": "DELETE /nodes/{node}/disks/directory/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/directory/{name}", + "section": "nodes", + "summary": "delete", + "searchText": "DELETE\n/nodes/{node}/disks/directory/{name}\nnodes\ndelete\nUnmounts the storage and removes the mount unit.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disk so it can be repurposed afterwards." + }, + { + "id": "POST /nodes/{node}/disks/initgpt", + "title": "POST /nodes/{node}/disks/initgpt", + "method": "POST", + "path": "/nodes/{node}/disks/initgpt", + "section": "nodes", + "summary": "initgpt", + "searchText": "POST\n/nodes/{node}/disks/initgpt\nnodes\ninitgpt\nInitialize Disk with GPT\nnode string The cluster node name.\ndisk string Block device name\nuuid string UUID for the GPT table" + }, + { + "id": "GET /nodes/{node}/disks/list", + "title": "GET /nodes/{node}/disks/list", + "method": "GET", + "path": "/nodes/{node}/disks/list", + "section": "nodes", + "summary": "list", + "searchText": "GET\n/nodes/{node}/disks/list\nnodes\nlist\nList local disks.\nnode string The cluster node name.\ninclude-partitions boolean Also include partitions.\nskipsmart boolean Skip smart checks.\ntype string Only list specific types of disks. unused journal_disks" + }, + { + "id": "GET /nodes/{node}/disks/lvm", + "title": "GET /nodes/{node}/disks/lvm", + "method": "GET", + "path": "/nodes/{node}/disks/lvm", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/disks/lvm\nnodes\nindex\nList LVM Volume Groups\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/lvm", + "title": "POST /nodes/{node}/disks/lvm", + "method": "POST", + "path": "/nodes/{node}/disks/lvm", + "section": "nodes", + "summary": "create", + "searchText": "POST\n/nodes/{node}/disks/lvm\nnodes\ncreate\nCreate an LVM Volume Group\nnode string The cluster node name.\ndevice string The block device you want to create the volume group on\nname string The storage identifier.\nadd_storage boolean Configure storage using the Volume Group" + }, + { + "id": "DELETE /nodes/{node}/disks/lvm/{name}", + "title": "DELETE /nodes/{node}/disks/lvm/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/lvm/{name}", + "section": "nodes", + "summary": "delete", + "searchText": "DELETE\n/nodes/{node}/disks/lvm/{name}\nnodes\ndelete\nRemove an LVM Volume Group.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards." + }, + { + "id": "GET /nodes/{node}/disks/lvmthin", + "title": "GET /nodes/{node}/disks/lvmthin", + "method": "GET", + "path": "/nodes/{node}/disks/lvmthin", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/disks/lvmthin\nnodes\nindex\nList LVM thinpools\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/lvmthin", + "title": "POST /nodes/{node}/disks/lvmthin", + "method": "POST", + "path": "/nodes/{node}/disks/lvmthin", + "section": "nodes", + "summary": "create", + "searchText": "POST\n/nodes/{node}/disks/lvmthin\nnodes\ncreate\nCreate an LVM thinpool\nnode string The cluster node name.\ndevice string The block device you want to create the thinpool on.\nname string The storage identifier.\nadd_storage boolean Configure storage using the thinpool." + }, + { + "id": "DELETE /nodes/{node}/disks/lvmthin/{name}", + "title": "DELETE /nodes/{node}/disks/lvmthin/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/lvmthin/{name}", + "section": "nodes", + "summary": "delete", + "searchText": "DELETE\n/nodes/{node}/disks/lvmthin/{name}\nnodes\ndelete\nRemove an LVM thin pool.\nname string The storage identifier.\nnode string The cluster node name.\nvolume-group string The storage identifier.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards." + }, + { + "id": "GET /nodes/{node}/disks/smart", + "title": "GET /nodes/{node}/disks/smart", + "method": "GET", + "path": "/nodes/{node}/disks/smart", + "section": "nodes", + "summary": "smart", + "searchText": "GET\n/nodes/{node}/disks/smart\nnodes\nsmart\nGet SMART Health of a disk.\nnode string The cluster node name.\ndisk string Block device name\nhealthonly boolean If true returns only the health status" + }, + { + "id": "PUT /nodes/{node}/disks/wipedisk", + "title": "PUT /nodes/{node}/disks/wipedisk", + "method": "PUT", + "path": "/nodes/{node}/disks/wipedisk", + "section": "nodes", + "summary": "wipe_disk", + "searchText": "PUT\n/nodes/{node}/disks/wipedisk\nnodes\nwipe_disk\nWipe a disk or partition.\nnode string The cluster node name.\ndisk string Block device name" + }, + { + "id": "GET /nodes/{node}/disks/zfs", + "title": "GET /nodes/{node}/disks/zfs", + "method": "GET", + "path": "/nodes/{node}/disks/zfs", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/disks/zfs\nnodes\nindex\nList Zpools.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/disks/zfs", + "title": "POST /nodes/{node}/disks/zfs", + "method": "POST", + "path": "/nodes/{node}/disks/zfs", + "section": "nodes", + "summary": "create", + "searchText": "POST\n/nodes/{node}/disks/zfs\nnodes\ncreate\nCreate a ZFS pool.\nnode string The cluster node name.\ndevices string The block devices you want to create the zpool on.\nname string The storage identifier.\nraidlevel string The RAID level to use. single mirror raid10 raidz raidz2 raidz3 draid draid2 draid3\nadd_storage boolean Configure storage using the zpool.\nashift integer Pool sector size exponent.\ncompression string The compression algorithm to use. on off gzip lz4 lzjb zle zstd\ndraid-config string" + }, + { + "id": "DELETE /nodes/{node}/disks/zfs/{name}", + "title": "DELETE /nodes/{node}/disks/zfs/{name}", + "method": "DELETE", + "path": "/nodes/{node}/disks/zfs/{name}", + "section": "nodes", + "summary": "delete", + "searchText": "DELETE\n/nodes/{node}/disks/zfs/{name}\nnodes\ndelete\nDestroy a ZFS pool.\nname string The storage identifier.\nnode string The cluster node name.\ncleanup-config boolean Marks associated storage(s) as not available on this node anymore or removes them from the configuration (if configured for this node only).\ncleanup-disks boolean Also wipe disks so they can be repurposed afterwards." + }, + { + "id": "GET /nodes/{node}/disks/zfs/{name}", + "title": "GET /nodes/{node}/disks/zfs/{name}", + "method": "GET", + "path": "/nodes/{node}/disks/zfs/{name}", + "section": "nodes", + "summary": "detail", + "searchText": "GET\n/nodes/{node}/disks/zfs/{name}\nnodes\ndetail\nGet details about a zpool.\nname string The storage identifier.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/dns", + "title": "GET /nodes/{node}/dns", + "method": "GET", + "path": "/nodes/{node}/dns", + "section": "nodes", + "summary": "dns", + "searchText": "GET\n/nodes/{node}/dns\nnodes\ndns\nRead DNS settings.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/dns", + "title": "PUT /nodes/{node}/dns", + "method": "PUT", + "path": "/nodes/{node}/dns", + "section": "nodes", + "summary": "update_dns", + "searchText": "PUT\n/nodes/{node}/dns\nnodes\nupdate_dns\nWrite DNS settings.\nnode string The cluster node name.\nsearch string Search domain for host-name lookup.\ndns1 string First name server IP address.\ndns2 string Second name server IP address.\ndns3 string Third name server IP address." + }, + { + "id": "POST /nodes/{node}/execute", + "title": "POST /nodes/{node}/execute", + "method": "POST", + "path": "/nodes/{node}/execute", + "section": "nodes", + "summary": "execute", + "searchText": "POST\n/nodes/{node}/execute\nnodes\nexecute\nExecute multiple commands in order, root only.\nnode string The cluster node name.\ncommands string JSON encoded array of commands." + }, + { + "id": "GET /nodes/{node}/firewall", + "title": "GET /nodes/{node}/firewall", + "method": "GET", + "path": "/nodes/{node}/firewall", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/firewall/log", + "title": "GET /nodes/{node}/firewall/log", + "method": "GET", + "path": "/nodes/{node}/firewall/log", + "section": "nodes", + "summary": "log", + "searchText": "GET\n/nodes/{node}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch." + }, + { + "id": "GET /nodes/{node}/firewall/options", + "title": "GET /nodes/{node}/firewall/options", + "method": "GET", + "path": "/nodes/{node}/firewall/options", + "section": "nodes", + "summary": "get_options", + "searchText": "GET\n/nodes/{node}/firewall/options\nnodes\nget_options\nGet host firewall options.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/firewall/options", + "title": "PUT /nodes/{node}/firewall/options", + "method": "PUT", + "path": "/nodes/{node}/firewall/options", + "section": "nodes", + "summary": "set_options", + "searchText": "PUT\n/nodes/{node}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable host firewall rules.\nlog_level_forward string Log level for forwarded traffic. emerg alert crit err warning notice info debug nolog\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nlog_nf_conntrack boolean Enable logging of conntrack information.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\nnf_conntrack_allow_invalid boolean Allow invalid packets on connection tracking.\nnf_conntrack_helpers string Enable conntrack helpers for specific protocols. Supported protocols: amanda, ftp, irc, netbios-ns, pptp, sane, sip, snmp, tftp\nnf_conntrack_max integer Maximum number of tracked connections.\nnf_conntrack_tcp_timeout_established integer Conntrack established timeout.\nnf_conntrack_tcp_timeout_syn_recv integer Conntrack syn recv timeout.\nnftables boolean Enable nftables based firewall (tech preview)\nnosmurfs boolean Enable SMURFS filter.\nprotection_synflood boolean Enable synflood protection\nprotection_synflood_burst integer Synflood protection rate burst by ip src.\nprotection_synflood_rate integer Synflood protection rate syn/sec by ip src.\nsmurf_log_level string Log level for SMURFS filter. emerg alert crit err warning notice info debug nolog\ntcp_flags_log_level string Log level for illegal tcp flags filter. emerg alert crit err warning notice info debug nolog\ntcpflags boolean Filter illegal combinations of TCP flags." + }, + { + "id": "GET /nodes/{node}/firewall/rules", + "title": "GET /nodes/{node}/firewall/rules", + "method": "GET", + "path": "/nodes/{node}/firewall/rules", + "section": "nodes", + "summary": "get_rules", + "searchText": "GET\n/nodes/{node}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/firewall/rules", + "title": "POST /nodes/{node}/firewall/rules", + "method": "POST", + "path": "/nodes/{node}/firewall/rules", + "section": "nodes", + "summary": "create_rule", + "searchText": "POST\n/nodes/{node}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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." + }, + { + "id": "DELETE /nodes/{node}/firewall/rules/{pos}", + "title": "DELETE /nodes/{node}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/nodes/{node}/firewall/rules/{pos}", + "section": "nodes", + "summary": "delete_rule", + "searchText": "DELETE\n/nodes/{node}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /nodes/{node}/firewall/rules/{pos}", + "title": "GET /nodes/{node}/firewall/rules/{pos}", + "method": "GET", + "path": "/nodes/{node}/firewall/rules/{pos}", + "section": "nodes", + "summary": "get_rule", + "searchText": "GET\n/nodes/{node}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\npos integer Update rule at position ." + }, + { + "id": "PUT /nodes/{node}/firewall/rules/{pos}", + "title": "PUT /nodes/{node}/firewall/rules/{pos}", + "method": "PUT", + "path": "/nodes/{node}/firewall/rules/{pos}", + "section": "nodes", + "summary": "update_rule", + "searchText": "PUT\n/nodes/{node}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group" + }, + { + "id": "GET /nodes/{node}/hardware", + "title": "GET /nodes/{node}/hardware", + "method": "GET", + "path": "/nodes/{node}/hardware", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/hardware\nnodes\nindex\nIndex of hardware types\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/hardware/pci", + "title": "GET /nodes/{node}/hardware/pci", + "method": "GET", + "path": "/nodes/{node}/hardware/pci", + "section": "nodes", + "summary": "pci_scan", + "searchText": "GET\n/nodes/{node}/hardware/pci\nnodes\npci_scan\nList local PCI devices.\nnode string The cluster node name.\npci-class-blacklist string A list of blacklisted PCI classes, which will not be returned. Following are filtered by default: Memory Controller (05), Bridge (06) and Processor (0b).\nverbose boolean If disabled, does only print the PCI IDs. Otherwise, additional information like vendor and device will be returned." + }, + { + "id": "GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "title": "GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "method": "GET", + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}", + "section": "nodes", + "summary": "pci_index", + "searchText": "GET\n/nodes/{node}/hardware/pci/{pci-id-or-mapping}\nnodes\npci_index\nIndex of available pci methods\nnode string The cluster node name.\npci-id-or-mapping string" + }, + { + "id": "GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "title": "GET /nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "method": "GET", + "path": "/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev", + "section": "nodes", + "summary": "mdevscan", + "searchText": "GET\n/nodes/{node}/hardware/pci/{pci-id-or-mapping}/mdev\nnodes\nmdevscan\nList mediated device types for given PCI device.\nnode string The cluster node name.\npci-id-or-mapping string The PCI ID or mapping to list the mdev types for." + }, + { + "id": "GET /nodes/{node}/hardware/usb", + "title": "GET /nodes/{node}/hardware/usb", + "method": "GET", + "path": "/nodes/{node}/hardware/usb", + "section": "nodes", + "summary": "usbscan", + "searchText": "GET\n/nodes/{node}/hardware/usb\nnodes\nusbscan\nList local USB devices.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/hosts", + "title": "GET /nodes/{node}/hosts", + "method": "GET", + "path": "/nodes/{node}/hosts", + "section": "nodes", + "summary": "get_etc_hosts", + "searchText": "GET\n/nodes/{node}/hosts\nnodes\nget_etc_hosts\nGet the content of /etc/hosts.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/hosts", + "title": "POST /nodes/{node}/hosts", + "method": "POST", + "path": "/nodes/{node}/hosts", + "section": "nodes", + "summary": "write_etc_hosts", + "searchText": "POST\n/nodes/{node}/hosts\nnodes\nwrite_etc_hosts\nWrite /etc/hosts.\nnode string The cluster node name.\ndata string The target content of /etc/hosts.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications." + }, + { + "id": "GET /nodes/{node}/journal", + "title": "GET /nodes/{node}/journal", + "method": "GET", + "path": "/nodes/{node}/journal", + "section": "nodes", + "summary": "journal", + "searchText": "GET\n/nodes/{node}/journal\nnodes\njournal\nRead Journal\nnode string The cluster node name.\nendcursor string End before the given Cursor. Conflicts with 'until'\nlastentries integer Limit to the last X lines. Conflicts with a range.\nsince integer Display all log since this UNIX epoch. Conflicts with 'startcursor'.\nstartcursor string Start after the given Cursor. Conflicts with 'since'\nuntil integer Display all log until this UNIX epoch. Conflicts with 'endcursor'." + }, + { + "id": "GET /nodes/{node}/lxc", + "title": "GET /nodes/{node}/lxc", + "method": "GET", + "path": "/nodes/{node}/lxc", + "section": "nodes", + "summary": "vmlist", + "searchText": "GET\n/nodes/{node}/lxc\nnodes\nvmlist\nLXC container index (per node).\nnode string The cluster node name.\ncontainer\nct\ncontainer\nct" + }, + { + "id": "POST /nodes/{node}/lxc", + "title": "POST /nodes/{node}/lxc", + "method": "POST", + "path": "/nodes/{node}/lxc", + "section": "nodes", + "summary": "create_vm", + "searchText": "POST\n/nodes/{node}/lxc\nnodes\ncreate_vm\nCreate or restore a container.\nnode string The cluster node name.\nostemplate string The OS template or backup file.\nvmid integer The (unique) ID of the VM.\narch string OS architecture type. amd64 i386 arm64 armhf riscv32 riscv64\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ncmode string 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). shell console tty\nconsole boolean Attach a console device (/dev/console) to the container.\ncores integer The number of cores assigned to the container. A container can use all available cores by default.\ncpulimit number 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.\ncpuunits integer CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.\ndebug boolean Try to be more verbose. For now this only enables debug log-level on start.\ndescription string Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.\ndev[n] string Device to pass through to the container\nentrypoint string Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.\nenv string The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.\nfeatures string Allow containers access to advanced features.\nforce boolean Allow to overwrite existing container.\nha-managed boolean Add the CT as a HA resource after it was created.\nhookscript string Script that will be executed during various steps in the containers lifetime.\nhostname string Set a host name for the container.\nignore-unpack-errors boolean Ignore errors when extracting the template.\nlock string Lock/unlock the container. backup create destroyed disk fstrim migrate mounted rollback snapshot snapshot-delete\nmemory integer Amount of RAM for the container in MB.\nmp[n] string Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.\nnameserver string Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nnet[n] string Specifies network interfaces for the container.\nonboot boolean Specifies whether a container will be started during system bootup.\nostype string 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. debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo nixos unmanaged\npassword string Sets root password inside container.\npool string Add the VM to the specified pool.\nprotection boolean Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.\nrestore boolean Mark this as restore task.\nrootfs string Use volume as container root.\nsearchdomain string Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nssh-public-keys string Setup public SSH keys (one key per line, OpenSSH format).\nstart boolean Start the CT after its creation finished successfully.\nstartup string 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.\nstorage string Default Storage.\nswap integer Amount of SWAP for the container in MB.\ntags string Tags of the Container. This is only meta information.\ntemplate boolean Enable/disable Template.\ntimezone string 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\ntty integer Specify the number of tty available to the container\nunique boolean Assign a unique random ethernet address.\nunprivileged boolean 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.)\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\ncontainer\nct\ncontainer\nct" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}", + "title": "DELETE /nodes/{node}/lxc/{vmid}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}", + "section": "nodes", + "summary": "destroy_vm", + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}\nnodes\ndestroy_vm\nDestroy the container (also delete all uses files).\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndestroy-unreferenced-disks boolean If set, destroy additionally all disks with the VMID from all enabled storages which are not referenced in the config.\nforce boolean Force destroy, even if running.\npurge boolean Remove container from all related configurations. For example, backup jobs, replication jobs or HA. Related ACLs and Firewall entries will *always* be removed.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}", + "title": "GET /nodes/{node}/lxc/{vmid}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}", + "section": "nodes", + "summary": "vmdiridx", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}\nnodes\nvmdiridx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/clone", + "title": "POST /nodes/{node}/lxc/{vmid}/clone", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/clone", + "section": "nodes", + "summary": "clone_vm", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/clone\nnodes\nclone_vm\nCreate a container clone/copy\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnewid integer VMID for the clone.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndescription string Description for the new CT.\nfull boolean 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.\nhostname string Set a hostname for the new CT.\npool string Add the new CT to the specified pool.\nsnapname string The name of the snapshot.\nstorage string Target storage for full clone.\ntarget string Target node. Only allowed if the original VM is on shared storage.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template\ncontainer\nct\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/config", + "title": "GET /nodes/{node}/lxc/{vmid}/config", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/config", + "section": "nodes", + "summary": "vm_config", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/config\nnodes\nvm_config\nGet container configuration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncurrent boolean Get current values (instead of pending values).\nsnapshot string Fetch config values from given snapshot.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/config", + "title": "PUT /nodes/{node}/lxc/{vmid}/config", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/config", + "section": "nodes", + "summary": "update_vm", + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/config\nnodes\nupdate_vm\nSet container options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\narch string OS architecture type. amd64 i386 arm64 armhf riscv32 riscv64\ncmode string 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). shell console tty\nconsole boolean Attach a console device (/dev/console) to the container.\ncores integer The number of cores assigned to the container. A container can use all available cores by default.\ncpulimit number 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.\ncpuunits integer CPU weight for a container, will be clamped to [1, 10000] in cgroup v2.\ndebug boolean Try to be more verbose. For now this only enables debug log-level on start.\ndelete string A list of settings you want to delete.\ndescription string Description for the Container. Shown in the web-interface CT's summary. This is saved as comment inside the configuration file.\ndev[n] string Device to pass through to the container\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nentrypoint string Command to run as init, optionally with arguments; may start with an absolute path, relative path, or a binary in $PATH.\nenv string The container runtime environment as NUL-separated list. Replaces any lxc.environment.runtime entries in the config.\nfeatures string Allow containers access to advanced features.\nhookscript string Script that will be executed during various steps in the containers lifetime.\nhostname string Set a host name for the container.\nlock string Lock/unlock the container. backup create destroyed disk fstrim migrate mounted rollback snapshot snapshot-delete\nmemory integer Amount of RAM for the container in MB.\nmp[n] string Use volume as container mount point. Use the special syntax STORAGE_ID:SIZE_IN_GiB to allocate a new volume.\nnameserver string Sets DNS server IP address for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nnet[n] string Specifies network interfaces for the container.\nonboot boolean Specifies whether a container will be started during system bootup.\nostype string 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. debian devuan ubuntu centos fedora opensuse archlinux alpine gentoo nixos unmanaged\nprotection boolean Sets the protection flag of the container. This will prevent the CT or CT's disk remove/update operation.\nrevert string Revert a pending change.\nrootfs string Use volume as container root.\nsearchdomain string Sets DNS search domains for a container. Create will automatically use the setting from the host if you neither set searchdomain nor nameserver.\nstartup string 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.\nswap integer Amount of SWAP for the container in MB.\ntags string Tags of the Container. This is only meta information.\ntemplate boolean Enable/disable Template.\ntimezone string 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\ntty integer Specify the number of tty available to the container\nunprivileged boolean 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.)\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/feature", + "title": "GET /nodes/{node}/lxc/{vmid}/feature", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/feature", + "section": "nodes", + "summary": "vm_feature", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/feature\nnodes\nvm_feature\nCheck if feature for virtual machine is available.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfeature string Feature to check. snapshot clone copy\nsnapname string The name of the snapshot.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/aliases", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/aliases", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "get_aliases", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/aliases\nnodes\nget_aliases\nList aliases\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/aliases", + "title": "POST /nodes/{node}/lxc/{vmid}/firewall/aliases", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "create_alias", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/aliases\nnodes\ncreate_alias\nCreate IP or Network Alias.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "title": "DELETE /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "remove_alias", + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "read_alias", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nread_alias\nRead alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "title": "PUT /nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "update_alias", + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/aliases/{name}\nnodes\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "ipset_index", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset\nnodes\nipset_index\nList IPSets\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/ipset", + "title": "POST /nodes/{node}/lxc/{vmid}/firewall/ipset", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "create_ipset", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/ipset\nnodes\ncreate_ipset\nCreate new IPSet\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "title": "DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "delete_ipset", + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\ndelete_ipset\nDelete IPSet\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce boolean Delete all members of the IPSet, if there are any.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "get_ipset", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\nget_ipset\nList IPSet content\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "title": "POST /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "create_ip", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}\nnodes\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "title": "DELETE /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "remove_ip", + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "read_ip", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "title": "PUT /nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "update_ip", + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/log", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/log", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/log", + "section": "nodes", + "summary": "log", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/options", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/options", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "section": "nodes", + "summary": "get_options", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/options\nnodes\nget_options\nGet VM firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/options", + "title": "PUT /nodes/{node}/lxc/{vmid}/firewall/options", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/options", + "section": "nodes", + "summary": "set_options", + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndelete string A list of settings you want to delete.\ndhcp boolean Enable DHCP.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nipfilter boolean 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.\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nmacfilter boolean Enable/disable MAC address filter.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP\nradv boolean Allow sending Router Advertisement.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/refs", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/refs", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/refs", + "section": "nodes", + "summary": "refs", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/refs\nnodes\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Only list references of specified type. alias ipset\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/rules", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/rules", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "section": "nodes", + "summary": "get_rules", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/firewall/rules", + "title": "POST /nodes/{node}/lxc/{vmid}/firewall/rules", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules", + "section": "nodes", + "summary": "create_rule", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "title": "DELETE /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "delete_rule", + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "title": "GET /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "get_rule", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "title": "PUT /nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "update_rule", + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/interfaces", + "title": "GET /nodes/{node}/lxc/{vmid}/interfaces", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/interfaces", + "section": "nodes", + "summary": "ip", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/interfaces\nnodes\nip\nGet IP addresses of the specified container interface.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/migrate", + "title": "GET /nodes/{node}/lxc/{vmid}/migrate", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm_precondition", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/migrate\nnodes\nmigrate_vm_precondition\nGet preconditions for migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/migrate", + "title": "POST /nodes/{node}/lxc/{vmid}/migrate", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/migrate\nnodes\nmigrate_vm\nMigrate the container to another node. Creates a new migration task.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\nonline boolean Use online/live migration.\nrestart boolean Use restart migration\ntarget-storage string 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.\ntimeout integer Timeout in seconds for shutdown for restart migration\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/move_volume", + "title": "POST /nodes/{node}/lxc/{vmid}/move_volume", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/move_volume", + "section": "nodes", + "summary": "move_volume", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/move_volume\nnodes\nmove_volume\nMove a rootfs-/mp-volume to a different storage or to a different container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvolume string Volume which will be moved. 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\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndelete boolean Delete the original volume after successful copy. By default the original is kept as an unused volume entry.\ndigest string Prevent changes if current configuration file has different SHA1 \" .\n\t\t \"digest. This can be used to prevent concurrent modifications.\nstorage string Target Storage.\ntarget-digest string 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.\ntarget-vmid integer The (unique) ID of the VM.\ntarget-volume string The config key the volume will be moved to. Default is the source volume key. 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\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/mtunnel", + "title": "POST /nodes/{node}/lxc/{vmid}/mtunnel", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/mtunnel", + "section": "nodes", + "summary": "mtunnel", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/mtunnel\nnodes\nmtunnel\nMigration tunnel endpoint - only for internal use by CT migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nbridges string List of network bridges to check availability. Will be checked again for actually used bridges during migration.\nstorages string List of storages to check permission and availability. Will be checked again for all actually used storages during migration.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "title": "GET /nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/mtunnelwebsocket", + "section": "nodes", + "summary": "mtunnelwebsocket", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/mtunnelwebsocket\nnodes\nmtunnelwebsocket\nMigration tunnel endpoint for websocket upgrade - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsocket string unix socket to forward to\nticket string ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/pending", + "title": "GET /nodes/{node}/lxc/{vmid}/pending", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/pending", + "section": "nodes", + "summary": "vm_pending", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/pending\nnodes\nvm_pending\nGet container configuration, including pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/remote_migrate", + "title": "POST /nodes/{node}/lxc/{vmid}/remote_migrate", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/remote_migrate", + "section": "nodes", + "summary": "remote_migrate_vm", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/remote_migrate\nnodes\nremote_migrate_vm\nMigrate the container to another cluster. Creates a new migration task. EXPERIMENTAL feature!\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget-bridge string 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.\ntarget-endpoint string Remote target endpoint\ntarget-storage string 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.\nbwlimit number Override I/O bandwidth limit (in KiB/s).\ndelete boolean 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.\nonline boolean Use online/live migration.\nrestart boolean Use restart migration\ntarget-vmid integer The (unique) ID of the VM.\ntimeout integer Timeout in seconds for shutdown for restart migration\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/resize", + "title": "PUT /nodes/{node}/lxc/{vmid}/resize", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/resize", + "section": "nodes", + "summary": "resize_vm", + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/resize\nnodes\nresize_vm\nResize a container mount point.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to resize. 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\nsize string 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.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/rrd", + "title": "GET /nodes/{node}/lxc/{vmid}/rrd", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/rrd", + "section": "nodes", + "summary": "rrd", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/rrd\nnodes\nrrd\nRead VM RRD statistics (returns PNG)\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/rrddata", + "title": "GET /nodes/{node}/lxc/{vmid}/rrddata", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/rrddata", + "section": "nodes", + "summary": "rrddata", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/rrddata\nnodes\nrrddata\nRead VM RRD statistics\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/snapshot", + "title": "GET /nodes/{node}/lxc/{vmid}/snapshot", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "section": "nodes", + "summary": "list", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/snapshot\nnodes\nlist\nList all snapshots.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/snapshot", + "title": "POST /nodes/{node}/lxc/{vmid}/snapshot", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/snapshot", + "section": "nodes", + "summary": "snapshot", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/snapshot\nnodes\nsnapshot\nSnapshot a container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsnapname string The name of the snapshot.\ndescription string A textual description or comment.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "DELETE /nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "title": "DELETE /nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "method": "DELETE", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "delsnapshot", + "searchText": "DELETE\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}\nnodes\ndelsnapshot\nDelete a LXC snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nforce boolean For removal from config file, even if removing disk snapshots fails.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "title": "GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "snapshot_cmd_idx", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}\nnodes\nsnapshot_cmd_idx\nsnapshot_cmd_idx\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "title": "GET /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "get_snapshot_config", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config\nnodes\nget_snapshot_config\nGet snapshot configuration\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "PUT /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "title": "PUT /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "method": "PUT", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "update_snapshot_config", + "searchText": "PUT\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/config\nnodes\nupdate_snapshot_config\nUpdate snapshot metadata.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ndescription string A textual description or comment.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "title": "POST /nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback", + "section": "nodes", + "summary": "rollback", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/snapshot/{snapname}/rollback\nnodes\nrollback\nRollback LXC state to specified snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nstart boolean Whether the container should get started after rolling back successfully\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\ncontainer\nct\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/spiceproxy", + "title": "POST /nodes/{node}/lxc/{vmid}/spiceproxy", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/spiceproxy", + "section": "nodes", + "summary": "spiceproxy", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/spiceproxy\nnodes\nspiceproxy\nReturns a SPICE configuration to connect to the CT.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nproxy string 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).\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/status", + "title": "GET /nodes/{node}/lxc/{vmid}/status", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/status", + "section": "nodes", + "summary": "vmcmdidx", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/status\nnodes\nvmcmdidx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/status/current", + "title": "GET /nodes/{node}/lxc/{vmid}/status/current", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/status/current", + "section": "nodes", + "summary": "vm_status", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/status/current\nnodes\nvm_status\nGet virtual machine status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/reboot", + "title": "POST /nodes/{node}/lxc/{vmid}/status/reboot", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/reboot", + "section": "nodes", + "summary": "vm_reboot", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/reboot\nnodes\nvm_reboot\nReboot the container by shutting it down, and starting it again. Applies pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeout integer Wait maximal timeout seconds for the shutdown.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/resume", + "title": "POST /nodes/{node}/lxc/{vmid}/status/resume", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/resume", + "section": "nodes", + "summary": "vm_resume", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/resume\nnodes\nvm_resume\nResume the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/shutdown", + "title": "POST /nodes/{node}/lxc/{vmid}/status/shutdown", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/shutdown", + "section": "nodes", + "summary": "vm_shutdown", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/shutdown\nnodes\nvm_shutdown\nShutdown the container. This will trigger a clean shutdown of the container, see lxc-stop(1) for details.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforceStop boolean Make sure the Container stops.\ntimeout integer Wait maximal timeout seconds.\ncontainer\nct\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop\ncontainer\nct\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/start", + "title": "POST /nodes/{node}/lxc/{vmid}/status/start", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/start", + "section": "nodes", + "summary": "vm_start", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/start\nnodes\nvm_start\nStart the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndebug boolean If set, enables very verbose debug log-level on start.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ncontainer\nct\nguest id\nvm id\ncontainer id\nstart\nboot\npower on\ncontainer\nct\nguest id\nvm id\ncontainer id\nstart\nboot\npower on" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/stop", + "title": "POST /nodes/{node}/lxc/{vmid}/status/stop", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/stop", + "section": "nodes", + "summary": "vm_stop", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/stop\nnodes\nvm_stop\nStop the container. This will abruptly stop all processes running in the container.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\noverrule-shutdown boolean Try to abort active 'vzshutdown' tasks before stopping.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ncontainer\nct\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off\ncontainer\nct\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/status/suspend", + "title": "POST /nodes/{node}/lxc/{vmid}/status/suspend", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/status/suspend", + "section": "nodes", + "summary": "vm_suspend", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/status/suspend\nnodes\nvm_suspend\nSuspend the container. This is experimental.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/template", + "title": "POST /nodes/{node}/lxc/{vmid}/template", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/template", + "section": "nodes", + "summary": "template", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/template\nnodes\ntemplate\nCreate a Template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/termproxy", + "title": "POST /nodes/{node}/lxc/{vmid}/termproxy", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/termproxy", + "section": "nodes", + "summary": "termproxy", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/termproxy\nnodes\ntermproxy\nCreates a TCP proxy connection.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/lxc/{vmid}/vncproxy", + "title": "POST /nodes/{node}/lxc/{vmid}/vncproxy", + "method": "POST", + "path": "/nodes/{node}/lxc/{vmid}/vncproxy", + "section": "nodes", + "summary": "vncproxy", + "searchText": "POST\n/nodes/{node}/lxc/{vmid}/vncproxy\nnodes\nvncproxy\nCreates a TCP VNC proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nheight integer sets the height of the console in pixels.\nwebsocket boolean use websocket instead of standard VNC.\nwidth integer sets the width of the console in pixels.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/lxc/{vmid}/vncwebsocket", + "title": "GET /nodes/{node}/lxc/{vmid}/vncwebsocket", + "method": "GET", + "path": "/nodes/{node}/lxc/{vmid}/vncwebsocket", + "section": "nodes", + "summary": "vncwebsocket", + "searchText": "GET\n/nodes/{node}/lxc/{vmid}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nport integer Port number returned by previous vncproxy call.\nvncticket string Ticket from previous call to vncproxy.\ncontainer\nct\nguest id\nvm id\ncontainer id\ncontainer\nct\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/migrateall", + "title": "POST /nodes/{node}/migrateall", + "method": "POST", + "path": "/nodes/{node}/migrateall", + "section": "nodes", + "summary": "migrateall", + "searchText": "POST\n/nodes/{node}/migrateall\nnodes\nmigrateall\nMigrate all VMs and Containers.\nnode string The cluster node name.\ntarget string Target node.\nmax-workers integer Maximal number of parallel migration job. If not set, uses'max_workers' from datacenter.cfg. One of both must be set!\nmaxworkers integer 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.\nvms string Only consider Guests with these IDs.\nwith-local-disks boolean Enable live storage migration for local disk" + }, + { + "id": "GET /nodes/{node}/netstat", + "title": "GET /nodes/{node}/netstat", + "method": "GET", + "path": "/nodes/{node}/netstat", + "section": "nodes", + "summary": "netstat", + "searchText": "GET\n/nodes/{node}/netstat\nnodes\nnetstat\nRead tap/vm network device interface counters\nnode string The cluster node name." + }, + { + "id": "DELETE /nodes/{node}/network", + "title": "DELETE /nodes/{node}/network", + "method": "DELETE", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "revert_network_changes", + "searchText": "DELETE\n/nodes/{node}/network\nnodes\nrevert_network_changes\nRevert network configuration changes.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/network", + "title": "GET /nodes/{node}/network", + "method": "GET", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/network\nnodes\nindex\nList available networks\nnode string The cluster node name.\ntype string Only list specific interface types. bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet any_bridge any_local_bridge include_sdn" + }, + { + "id": "POST /nodes/{node}/network", + "title": "POST /nodes/{node}/network", + "method": "POST", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "create_network", + "searchText": "POST\n/nodes/{node}/network\nnodes\ncreate_network\nCreate network device configuration\nnode string The cluster node name.\niface string Network interface name.\ntype string Network interface type bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet unknown\naddress string IP address.\naddress6 string IP address.\nautostart boolean Automatically start interface on boot.\nbond_mode string Bonding mode. balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb balance-slb lacp-balance-slb lacp-balance-tcp\nbond_xmit_hash_policy string Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. layer2 layer2+3 layer3+4\nbond-primary string Specify the primary interface for active-backup bond.\nbridge_ports string Specify the interfaces you want to add to your bridge.\nbridge_vids string Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.\nbridge_vlan_aware boolean Enable bridge vlan support.\ncidr string IPv4 CIDR.\ncidr6 string IPv6 CIDR.\ncomments string Comments\ncomments6 string Comments\ngateway string Default gateway address.\ngateway6 string Default ipv6 gateway address.\nmtu integer MTU.\nnetmask string Network mask.\nnetmask6 integer Network mask.\novs_bonds string Specify the interfaces used by the bonding device.\novs_bridge string The OVS bridge associated with a OVS port. This is required when you create an OVS port.\novs_options string OVS interface options.\novs_ports string Specify the interfaces you want to add to your bridge.\novs_tag integer Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)\nslaves string Specify the interfaces used by the bonding device.\nvlan-id integer vlan-id for a custom named vlan interface (ifupdown2 only).\nvlan-raw-device string Specify the raw interface for the vlan interface." + }, + { + "id": "PUT /nodes/{node}/network", + "title": "PUT /nodes/{node}/network", + "method": "PUT", + "path": "/nodes/{node}/network", + "section": "nodes", + "summary": "reload_network_config", + "searchText": "PUT\n/nodes/{node}/network\nnodes\nreload_network_config\nReload network configuration\nnode string The cluster node name.\nregenerate-frr boolean Whether FRR config generation should get skipped or not." + }, + { + "id": "DELETE /nodes/{node}/network/{iface}", + "title": "DELETE /nodes/{node}/network/{iface}", + "method": "DELETE", + "path": "/nodes/{node}/network/{iface}", + "section": "nodes", + "summary": "delete_network", + "searchText": "DELETE\n/nodes/{node}/network/{iface}\nnodes\ndelete_network\nDelete network device configuration\niface string Network interface name.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/network/{iface}", + "title": "GET /nodes/{node}/network/{iface}", + "method": "GET", + "path": "/nodes/{node}/network/{iface}", + "section": "nodes", + "summary": "network_config", + "searchText": "GET\n/nodes/{node}/network/{iface}\nnodes\nnetwork_config\nRead network device configuration\niface string Network interface name.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/network/{iface}", + "title": "PUT /nodes/{node}/network/{iface}", + "method": "PUT", + "path": "/nodes/{node}/network/{iface}", + "section": "nodes", + "summary": "update_network", + "searchText": "PUT\n/nodes/{node}/network/{iface}\nnodes\nupdate_network\nUpdate network device configuration\niface string Network interface name.\nnode string The cluster node name.\ntype string Network interface type bridge bond eth alias vlan fabric OVSBridge OVSBond OVSPort OVSIntPort vnet unknown\naddress string IP address.\naddress6 string IP address.\nautostart boolean Automatically start interface on boot.\nbond_mode string Bonding mode. balance-rr active-backup balance-xor broadcast 802.3ad balance-tlb balance-alb balance-slb lacp-balance-slb lacp-balance-tcp\nbond_xmit_hash_policy string Selects the transmit hash policy to use for slave selection in balance-xor and 802.3ad modes. layer2 layer2+3 layer3+4\nbond-primary string Specify the primary interface for active-backup bond.\nbridge_ports string Specify the interfaces you want to add to your bridge.\nbridge_vids string Specify the allowed VLANs. For example: '2 4 100-200'. Only used if the bridge is VLAN aware.\nbridge_vlan_aware boolean Enable bridge vlan support.\ncidr string IPv4 CIDR.\ncidr6 string IPv6 CIDR.\ncomments string Comments\ncomments6 string Comments\ndelete string A list of settings you want to delete.\ngateway string Default gateway address.\ngateway6 string Default ipv6 gateway address.\nmtu integer MTU.\nnetmask string Network mask.\nnetmask6 integer Network mask.\novs_bonds string Specify the interfaces used by the bonding device.\novs_bridge string The OVS bridge associated with a OVS port. This is required when you create an OVS port.\novs_options string OVS interface options.\novs_ports string Specify the interfaces you want to add to your bridge.\novs_tag integer Specify a VLan tag (used by OVSPort, OVSIntPort, OVSBond)\nslaves string Specify the interfaces used by the bonding device.\nvlan-id integer vlan-id for a custom named vlan interface (ifupdown2 only).\nvlan-raw-device string Specify the raw interface for the vlan interface." + }, + { + "id": "GET /nodes/{node}/qemu", + "title": "GET /nodes/{node}/qemu", + "method": "GET", + "path": "/nodes/{node}/qemu", + "section": "nodes", + "summary": "vmlist", + "searchText": "GET\n/nodes/{node}/qemu\nnodes\nvmlist\nVirtual machine index (per node).\nnode string The cluster node name.\nfull boolean Determine the full status of active VMs.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "POST /nodes/{node}/qemu", + "title": "POST /nodes/{node}/qemu", + "method": "POST", + "path": "/nodes/{node}/qemu", + "section": "nodes", + "summary": "create_vm", + "searchText": "POST\n/nodes/{node}/qemu\nnodes\ncreate_vm\nCreate or restore a virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\narchive string 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.\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\nefidisk0 string 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.\nforce boolean Allow to overwrite existing VM.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nha-managed boolean Add the VM as a HA resource after it was created.\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nimport-working-storage string A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlive-restore boolean Start the VM immediately while importing or restoring in the background.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\npool string Add the VM to the specified pool.\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstart boolean Start VM after it was created successfully.\nstartdate string 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'.\nstartup string 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.\nstorage string Default storage.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunique boolean Assign a unique random ethernet address.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest\nvm\nvirtual machine\nkvm guest" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}", + "title": "DELETE /nodes/{node}/qemu/{vmid}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}", + "section": "nodes", + "summary": "destroy_vm", + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}\nnodes\ndestroy_vm\nDestroy the VM and all used/owned volumes. Removes any VM specific permissions and firewall rules\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndestroy-unreferenced-disks boolean If set, destroy additionally all disks not referenced in the config but with a matching VMID from all enabled storages.\npurge boolean Remove VMID from configurations, like backup & replication jobs and HA.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}", + "title": "GET /nodes/{node}/qemu/{vmid}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}", + "section": "nodes", + "summary": "vmdiridx", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}\nnodes\nvmdiridx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent", + "title": "GET /nodes/{node}/qemu/{vmid}/agent", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent\nnodes\nindex\nQEMU Guest Agent command index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent", + "title": "POST /nodes/{node}/qemu/{vmid}/agent", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent", + "section": "nodes", + "summary": "agent", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent\nnodes\nagent\nExecute QEMU Guest Agent commands.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand string The QGA command. 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\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/exec", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/exec", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/exec", + "section": "nodes", + "summary": "exec", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/exec\nnodes\nexec\nExecutes the given command in the vm via the guest-agent and returns an object with the pid.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand array The command as a list of program + arguments.\ninput-data string Data to pass as 'input-data' to the guest. Usually treated as STDIN to 'command'.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/exec-status", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/exec-status", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/exec-status", + "section": "nodes", + "summary": "exec-status", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/exec-status\nnodes\nexec-status\nGets the status of the given pid started by the guest-agent\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npid integer The PID to query\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/file-read", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/file-read", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/file-read", + "section": "nodes", + "summary": "file-read", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/file-read\nnodes\nfile-read\nReads the given file via guest agent. Is limited to 16777216 bytes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfile string The path to the file\ncount integer Number of bytes to read.\ndecode boolean 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.\noffset integer Offset to start reading at\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/file-write", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/file-write", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/file-write", + "section": "nodes", + "summary": "file-write", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/file-write\nnodes\nfile-write\nWrites the given file via guest agent.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncontent string The content to write into the file.\nfile string The path to the file.\nencode boolean If set, the content will be encoded as base64 (required by QEMU).Otherwise the content needs to be encoded beforehand - defaults to true.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze", + "section": "nodes", + "summary": "fsfreeze-freeze", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-freeze\nnodes\nfsfreeze-freeze\nExecute fsfreeze-freeze.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status", + "section": "nodes", + "summary": "fsfreeze-status", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-status\nnodes\nfsfreeze-status\nExecute fsfreeze-status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw", + "section": "nodes", + "summary": "fsfreeze-thaw", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fsfreeze-thaw\nnodes\nfsfreeze-thaw\nExecute fsfreeze-thaw.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/fstrim", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/fstrim", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/fstrim", + "section": "nodes", + "summary": "fstrim", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/fstrim\nnodes\nfstrim\nExecute fstrim.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-fsinfo", + "section": "nodes", + "summary": "get-fsinfo", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-fsinfo\nnodes\nget-fsinfo\nExecute get-fsinfo.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-host-name", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-host-name", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-host-name", + "section": "nodes", + "summary": "get-host-name", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-host-name\nnodes\nget-host-name\nExecute get-host-name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info", + "section": "nodes", + "summary": "get-memory-block-info", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-memory-block-info\nnodes\nget-memory-block-info\nExecute get-memory-block-info.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks", + "section": "nodes", + "summary": "get-memory-blocks", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-memory-blocks\nnodes\nget-memory-blocks\nExecute get-memory-blocks.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-osinfo", + "section": "nodes", + "summary": "get-osinfo", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-osinfo\nnodes\nget-osinfo\nExecute get-osinfo.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-time", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-time", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-time", + "section": "nodes", + "summary": "get-time", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-time\nnodes\nget-time\nExecute get-time.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-timezone", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-timezone", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-timezone", + "section": "nodes", + "summary": "get-timezone", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-timezone\nnodes\nget-timezone\nExecute get-timezone.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-users", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-users", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-users", + "section": "nodes", + "summary": "get-users", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-users\nnodes\nget-users\nExecute get-users.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/get-vcpus", + "section": "nodes", + "summary": "get-vcpus", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/get-vcpus\nnodes\nget-vcpus\nExecute get-vcpus.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/info", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/info", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/info", + "section": "nodes", + "summary": "info", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/info\nnodes\ninfo\nExecute info.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "title": "GET /nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces", + "section": "nodes", + "summary": "network-get-interfaces", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/agent/network-get-interfaces\nnodes\nnetwork-get-interfaces\nExecute network-get-interfaces.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/ping", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/ping", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/ping", + "section": "nodes", + "summary": "ping", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/ping\nnodes\nping\nExecute ping.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/set-user-password", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/set-user-password", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/set-user-password", + "section": "nodes", + "summary": "set-user-password", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/set-user-password\nnodes\nset-user-password\nSets the password for the given user to the given password\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npassword string The new password.\nusername string The user to set the password for.\ncrypted boolean set to 1 if the password has already been passed through crypt()\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/shutdown", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/shutdown", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/shutdown", + "section": "nodes", + "summary": "shutdown", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/shutdown\nnodes\nshutdown\nExecute shutdown.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-disk", + "section": "nodes", + "summary": "suspend-disk", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-disk\nnodes\nsuspend-disk\nExecute suspend-disk.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid", + "section": "nodes", + "summary": "suspend-hybrid", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-hybrid\nnodes\nsuspend-hybrid\nExecute suspend-hybrid.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "title": "POST /nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/agent/suspend-ram", + "section": "nodes", + "summary": "suspend-ram", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/agent/suspend-ram\nnodes\nsuspend-ram\nExecute suspend-ram.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/clone", + "title": "POST /nodes/{node}/qemu/{vmid}/clone", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/clone", + "section": "nodes", + "summary": "clone_vm", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/clone\nnodes\nclone_vm\nCreate a copy of virtual machine/template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnewid integer VMID for the clone.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndescription string Description for the new VM.\nformat string Target format for file storage. Only valid for full clone. raw qcow2 vmdk\nfull boolean 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.\nname string Set a name for the new VM.\npool string Add the new VM to the specified pool.\nsnapname string The name of the snapshot.\nstorage string Target storage for full clone.\ntarget string Target node. Only allowed if the original VM is on shared storage.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncopy\nduplicate\ncreate from template" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/cloudinit", + "title": "GET /nodes/{node}/qemu/{vmid}/cloudinit", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "section": "nodes", + "summary": "cloudinit_pending", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/cloudinit\nnodes\ncloudinit_pending\nGet the cloudinit configuration with both current and pending values.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/cloudinit", + "title": "PUT /nodes/{node}/qemu/{vmid}/cloudinit", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/cloudinit", + "section": "nodes", + "summary": "cloudinit_update", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/cloudinit\nnodes\ncloudinit_update\nRegenerate and change cloudinit config drive.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/cloudinit/dump", + "title": "GET /nodes/{node}/qemu/{vmid}/cloudinit/dump", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/cloudinit/dump", + "section": "nodes", + "summary": "cloudinit_generated_config_dump", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/cloudinit/dump\nnodes\ncloudinit_generated_config_dump\nGet automatically generated cloudinit config.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Config type. user network meta\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/config", + "title": "GET /nodes/{node}/qemu/{vmid}/config", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/config", + "section": "nodes", + "summary": "vm_config", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/config\nnodes\nvm_config\nGet the virtual machine configuration with pending configuration changes applied. Set the 'current' parameter to get the current configuration instead.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncurrent boolean Get current values (instead of pending values).\nsnapshot string Fetch config values from given snapshot.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/config", + "title": "POST /nodes/{node}/qemu/{vmid}/config", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/config", + "section": "nodes", + "summary": "update_vm_async", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/config\nnodes\nupdate_vm_async\nSet virtual machine options (asynchronous API).\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nbackground_delay integer Time to wait for the task to finish. We return 'null' if the task finish within that time.\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndelete string A list of settings you want to delete.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nefidisk0 string 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.\nforce boolean 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.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nimport-working-storage string A file-based storage with 'images' content-type enabled, which is used as an intermediary extraction storage during import. Defaults to the source storage.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrevert string Revert a pending change.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstartdate string 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'.\nstartup string 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.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/config", + "title": "PUT /nodes/{node}/qemu/{vmid}/config", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/config", + "section": "nodes", + "summary": "update_vm", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/config\nnodes\nupdate_vm\nSet virtual machine options (synchronous API) - You should consider using the POST method instead for any actions involving hotplug or storage allocation.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nacpi boolean Enable/disable ACPI.\naffinity string List of host cores used to execute guest processes, for example: 0,5,8-11\nagent string Enable/disable communication with the QEMU Guest Agent and its properties.\nallow-ksm boolean Allow memory pages of this guest to be merged via KSM (Kernel Samepage Merging).\namd-sev string Secure Encrypted Virtualization (SEV) features by AMD CPUs\narch string Virtual processor architecture. Defaults to the host architecture. x86_64 aarch64\nargs string Arbitrary arguments passed to kvm.\naudio0 string Configure a audio device, useful in combination with QXL/Spice.\nautostart boolean Automatic restart after crash (currently ignored).\nballoon integer 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.\nbios string Select BIOS implementation. seabios ovmf\nboot string Specify guest boot order. Use the 'order=' sub-property as usage with no key or 'legacy=' is deprecated.\nbootdisk string Enable booting from specified disk. Deprecated: Use 'boot: order=foo;bar' instead.\ncdrom string This is an alias for option -ide2\ncicustom string cloud-init: Specify custom files to replace the automatically generated ones at start.\ncipassword string 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.\ncitype string 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. configdrive2 nocloud opennebula\nciupgrade boolean cloud-init: do an automatic package upgrade after the first boot.\nciuser string cloud-init: User name to change ssh keys and password for instead of the image's configured default user.\ncores integer The number of cores per socket.\ncpu string Emulated CPU type.\ncpulimit number Limit of CPU usage.\ncpuunits integer CPU weight for a VM, will be clamped to [1, 10000] in cgroup v2.\ndelete string A list of settings you want to delete.\ndescription string Description for the VM. Shown in the web-interface VM's summary. This is saved as comment inside the configuration file.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nefidisk0 string 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.\nforce boolean 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.\nfreeze boolean Freeze CPU at startup (use 'c' monitor command to start execution).\nhookscript string Script that will be executed during various steps in the vms lifetime.\nhostpci[n] string Map host PCI devices into guest.\nhotplug string 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.\nhugepages string 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. any 2 1024\nide[n] string 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.\nintel-tdx string Trusted Domain Extension (TDX) features by Intel CPUs\nipconfig[n] string 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.\nivshmem string Inter-VM shared memory. Useful for direct communication between VMs, or to the host.\nkeephugepages boolean Use together with hugepages. If enabled, hugepages will not not be deleted after VM shutdown and can be used for subsequent starts.\nkeyboard string Keyboard layout for VNC server. This option is generally not required and is often better handled from within the guest OS. 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\nkvm boolean Enable/disable KVM hardware virtualization.\nlocaltime boolean Set the real time clock (RTC) to local time. This is enabled by default if the `ostype` indicates a Microsoft Windows OS.\nlock string Lock/unlock the VM. backup clone create migrate rollback snapshot snapshot-delete suspending suspended\nmachine string Specify the QEMU machine.\nmemory string Memory properties.\nmigrate_downtime number 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).\nmigrate_speed integer Set maximum speed (in MB/s) for migrations. Value 0 is no limit.\nname string Set a name for the VM. Only used on the configuration web interface.\nnameserver string 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.\nnet[n] string Specify network devices.\nnuma boolean Enable/disable NUMA.\nnuma[n] string NUMA topology.\nonboot boolean Specifies whether a VM will be started during system bootup.\nostype string Specify guest operating system. other wxp w2k w2k3 w2k8 wvista win7 win8 win10 win11 l24 l26 solaris\nparallel[n] string Map host parallel devices (n is 0 to 2).\nprotection boolean Sets the protection flag of the VM. This will disable the remove VM and remove disk operations.\nreboot boolean Allow reboot. If set to '0' the VM exit on reboot.\nrevert string Revert a pending change.\nrng0 string Configure a VirtIO-based Random Number Generator.\nsata[n] string 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.\nscsi[n] string 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.\nscsihw string SCSI controller model lsi lsi53c810 virtio-scsi-pci virtio-scsi-single megasas pvscsi\nsearchdomain string 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.\nserial[n] string Create a serial device inside the VM (n is 0 to 3)\nshares integer 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nsmbios1 string Specify SMBIOS type 1 fields.\nsmp integer The number of CPUs. Please use option -sockets instead.\nsockets integer The number of CPU sockets.\nspice_enhancements string Configure additional enhancements for SPICE.\nsshkeys string cloud-init: Setup public SSH keys (one key per line, OpenSSH format).\nstartdate string 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'.\nstartup string 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.\ntablet boolean Enable/disable the USB tablet device.\ntags string Tags of the VM. This is only meta information.\ntdf boolean Enable/disable time drift fix.\ntemplate boolean Enable/disable Template.\ntpmstate0 string 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.\nunused[n] string Reference to unused volumes. This is used internally, and should not be modified manually.\nusb[n] string 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).\nvcpus integer Number of hotplugged vcpus.\nvga string Configure the VGA hardware.\nvirtio[n] string 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.\nvirtiofs[n] string Configuration for sharing a directory between host and guest using Virtio-fs.\nvmgenid string Set VM Generation ID. Use '1' to autogenerate on create or update, pass '0' to disable explicitly.\nvmstatestorage string Default storage for VM state volumes/files.\nwatchdog string Create a virtual hardware watchdog device.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/dbus-vmstate", + "title": "POST /nodes/{node}/qemu/{vmid}/dbus-vmstate", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/dbus-vmstate", + "section": "nodes", + "summary": "dbus_vmstate", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/dbus-vmstate\nnodes\ndbus_vmstate\nControl the dbus-vmstate helper for a given running VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Action to perform on the DBus VMState helper. start stop\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/feature", + "title": "GET /nodes/{node}/qemu/{vmid}/feature", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/feature", + "section": "nodes", + "summary": "vm_feature", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/feature\nnodes\nvm_feature\nCheck if feature for virtual machine is available.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nfeature string Feature to check. snapshot clone copy\nsnapname string The name of the snapshot.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall\nnodes\nindex\nDirectory index.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/aliases", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/aliases", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "get_aliases", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/aliases\nnodes\nget_aliases\nList aliases\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/aliases", + "title": "POST /nodes/{node}/qemu/{vmid}/firewall/aliases", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases", + "section": "nodes", + "summary": "create_alias", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/aliases\nnodes\ncreate_alias\nCreate IP or Network Alias.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\nname string Alias name.\ncomment string\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "title": "DELETE /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "remove_alias", + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nremove_alias\nRemove IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "read_alias", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nread_alias\nRead alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "title": "PUT /nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}", + "section": "nodes", + "summary": "update_alias", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/aliases/{name}\nnodes\nupdate_alias\nUpdate IP or Network alias.\nname string Alias name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing alias.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "ipset_index", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset\nnodes\nipset_index\nList IPSets\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/ipset", + "title": "POST /nodes/{node}/qemu/{vmid}/firewall/ipset", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset", + "section": "nodes", + "summary": "create_ipset", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/ipset\nnodes\ncreate_ipset\nCreate new IPSet\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nname string IP set name.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nrename string Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "title": "DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "delete_ipset", + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\ndelete_ipset\nDelete IPSet\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce boolean Delete all members of the IPSet, if there are any.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "get_ipset", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\nget_ipset\nList IPSet content\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "title": "POST /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}", + "section": "nodes", + "summary": "create_ip", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}\nnodes\ncreate_ip\nAdd IP or Network to IPSet.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncidr string Network/IP specification in CIDR format.\ncomment string\nnomatch boolean\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "title": "DELETE /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "remove_ip", + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nremove_ip\nRemove IP or Network from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "read_ip", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nread_ip\nRead IP or Network settings from IPSet.\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "title": "PUT /nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}", + "section": "nodes", + "summary": "update_ip", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/ipset/{name}/{cidr}\nnodes\nupdate_ip\nUpdate IP or Network settings\ncidr string Network/IP specification in CIDR format.\nname string IP set name.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncomment string\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nnomatch boolean\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/log", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/log", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/log", + "section": "nodes", + "summary": "log", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/log\nnodes\nlog\nRead firewall log\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nlimit integer\nsince integer Display log since this UNIX epoch.\nstart integer\nuntil integer Display log until this UNIX epoch.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/options", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/options", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "section": "nodes", + "summary": "get_options", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/options\nnodes\nget_options\nGet VM firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/options", + "title": "PUT /nodes/{node}/qemu/{vmid}/firewall/options", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/options", + "section": "nodes", + "summary": "set_options", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/options\nnodes\nset_options\nSet Firewall options.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndelete string A list of settings you want to delete.\ndhcp boolean Enable DHCP.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nenable boolean Enable/disable firewall rules.\nipfilter boolean 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.\nlog_level_in string Log level for incoming traffic. emerg alert crit err warning notice info debug nolog\nlog_level_out string Log level for outgoing traffic. emerg alert crit err warning notice info debug nolog\nmacfilter boolean Enable/disable MAC address filter.\nndp boolean Enable NDP (Neighbor Discovery Protocol).\npolicy_in string Input policy. ACCEPT REJECT DROP\npolicy_out string Output policy. ACCEPT REJECT DROP\nradv boolean Allow sending Router Advertisement.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/refs", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/refs", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/refs", + "section": "nodes", + "summary": "refs", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/refs\nnodes\nrefs\nLists possible IPSet/Alias reference which are allowed in source/dest properties.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntype string Only list references of specified type. alias ipset\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/rules", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/rules", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "section": "nodes", + "summary": "get_rules", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/rules\nnodes\nget_rules\nList rules.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/firewall/rules", + "title": "POST /nodes/{node}/qemu/{vmid}/firewall/rules", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules", + "section": "nodes", + "summary": "create_rule", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/firewall/rules\nnodes\ncreate_rule\nCreate new rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ntype string Rule type. in out forward group\ncomment string Descriptive comment.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\npos integer Update rule at position .\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "title": "DELETE /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "delete_rule", + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\ndelete_rule\nDelete rule.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "title": "GET /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "get_rule", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\nget_rule\nGet single rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "title": "PUT /nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}", + "section": "nodes", + "summary": "update_rule", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/firewall/rules/{pos}\nnodes\nupdate_rule\nModify rule data.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\npos integer Update rule at position .\naction string Rule action ('ACCEPT', 'DROP', 'REJECT') or security group name.\ncomment string Descriptive comment.\ndelete string A list of settings you want to delete.\ndest string 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.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndport string 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.\nenable integer Flag to enable/disable a rule.\nicmp-type string Specify icmp-type. Only valid if proto equals 'icmp' or 'icmpv6'/'ipv6-icmp'.\niface string Network interface name. You have to use network configuration key names for VMs and containers ('net\\d+'). Host related rules can use arbitrary strings.\nlog string Log level for firewall rule. emerg alert crit err warning notice info debug nolog\nmacro string Use predefined standard macro.\nmoveto integer Move rule to new position . Other arguments are ignored.\nproto string IP protocol. You can use protocol names ('tcp'/'udp') or simple numbers, as defined in '/etc/protocols'.\nsource string 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.\nsport string 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.\ntype string Rule type. in out forward group\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/migrate", + "title": "GET /nodes/{node}/qemu/{vmid}/migrate", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm_precondition", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/migrate\nnodes\nmigrate_vm_precondition\nGet preconditions for migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/migrate", + "title": "POST /nodes/{node}/qemu/{vmid}/migrate", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/migrate", + "section": "nodes", + "summary": "migrate_vm", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/migrate\nnodes\nmigrate_vm\nMigrate virtual machine. Creates a new migration task.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget string Target node.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\nforce boolean Allow to migrate VMs which use local devices. Only root may use this option.\nmigration_network string CIDR of the (sub) network that is used for migration.\nmigration_type string Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. secure insecure\nonline boolean Use online/live migration if VM is running. Ignored if VM is stopped.\ntargetstorage string 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.\nwith-conntrack-state boolean Whether to migrate conntrack entries for running VMs.\nwith-local-disks boolean Enable live storage migration for local disk\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/monitor", + "title": "POST /nodes/{node}/qemu/{vmid}/monitor", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/monitor", + "section": "nodes", + "summary": "monitor", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/monitor\nnodes\nmonitor\nExecute QEMU monitor commands.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ncommand string The monitor command.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/move_disk", + "title": "POST /nodes/{node}/qemu/{vmid}/move_disk", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/move_disk", + "section": "nodes", + "summary": "move_vm_disk", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/move_disk\nnodes\nmove_vm_disk\nMove volume to different storage or to a different VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to move. 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\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndelete boolean Delete the original disk after successful copy. By default the original disk is kept as unused disk.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nformat string Target Format. raw qcow2 vmdk\nstorage string Target storage.\ntarget-digest string Prevent changes if the current config file of the target VM has a different SHA1 digest. This can be used to detect concurrent modifications.\ntarget-disk string The config key the disk will be moved to on the target VM (for example, ide0 or scsi1). Default is the source disk key. 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\ntarget-vmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/mtunnel", + "title": "POST /nodes/{node}/qemu/{vmid}/mtunnel", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/mtunnel", + "section": "nodes", + "summary": "mtunnel", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/mtunnel\nnodes\nmtunnel\nMigration tunnel endpoint - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nbridges string List of network bridges to check availability. Will be checked again for actually used bridges during migration.\nstorages string List of storages to check permission and availability. Will be checked again for all actually used storages during migration.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "title": "GET /nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/mtunnelwebsocket", + "section": "nodes", + "summary": "mtunnelwebsocket", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/mtunnelwebsocket\nnodes\nmtunnelwebsocket\nMigration tunnel endpoint for websocket upgrade - only for internal use by VM migration.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsocket string unix socket to forward to\nticket string ticket return by initial 'mtunnel' API call, or retrieved via 'ticket' tunnel command\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/pending", + "title": "GET /nodes/{node}/qemu/{vmid}/pending", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/pending", + "section": "nodes", + "summary": "vm_pending", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/pending\nnodes\nvm_pending\nGet the virtual machine configuration with both current and pending values.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/remote_migrate", + "title": "POST /nodes/{node}/qemu/{vmid}/remote_migrate", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/remote_migrate", + "section": "nodes", + "summary": "remote_migrate_vm", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/remote_migrate\nnodes\nremote_migrate_vm\nMigrate virtual machine to a remote cluster. Creates a new migration task. EXPERIMENTAL feature!\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntarget-bridge string 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.\ntarget-endpoint string Remote target endpoint\ntarget-storage string 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.\nbwlimit integer Override I/O bandwidth limit (in KiB/s).\ndelete boolean 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.\nonline boolean Use online/live migration if VM is running. Ignored if VM is stopped.\ntarget-vmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/resize", + "title": "PUT /nodes/{node}/qemu/{vmid}/resize", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/resize", + "section": "nodes", + "summary": "resize_vm", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/resize\nnodes\nresize_vm\nExtend volume size.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string The disk you want to resize. 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\nsize string 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.\ndigest string Prevent changes if current configuration file has different SHA1 digest. This can be used to prevent concurrent modifications.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/rrd", + "title": "GET /nodes/{node}/qemu/{vmid}/rrd", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/rrd", + "section": "nodes", + "summary": "rrd", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/rrd\nnodes\nrrd\nRead VM RRD statistics (returns PNG)\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/rrddata", + "title": "GET /nodes/{node}/qemu/{vmid}/rrddata", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/rrddata", + "section": "nodes", + "summary": "rrddata", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/rrddata\nnodes\nrrddata\nRead VM RRD statistics\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/sendkey", + "title": "PUT /nodes/{node}/qemu/{vmid}/sendkey", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/sendkey", + "section": "nodes", + "summary": "vm_sendkey", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/sendkey\nnodes\nvm_sendkey\nSend key event to virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nkey string The key (qemu monitor encoding).\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/snapshot", + "title": "GET /nodes/{node}/qemu/{vmid}/snapshot", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "section": "nodes", + "summary": "snapshot_list", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/snapshot\nnodes\nsnapshot_list\nList all snapshots.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/snapshot", + "title": "POST /nodes/{node}/qemu/{vmid}/snapshot", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/snapshot", + "section": "nodes", + "summary": "snapshot", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/snapshot\nnodes\nsnapshot\nSnapshot a VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nsnapname string The name of the snapshot.\ndescription string A textual description or comment.\nvmstate boolean Save the vmstate\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "DELETE /nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "title": "DELETE /nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "method": "DELETE", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "delsnapshot", + "searchText": "DELETE\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}\nnodes\ndelsnapshot\nDelete a VM snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nforce boolean For removal from config file, even if removing disk snapshots fails.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "title": "GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}", + "section": "nodes", + "summary": "snapshot_cmd_idx", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}\nnodes\nsnapshot_cmd_idx\nsnapshot_cmd_idx\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "title": "GET /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "get_snapshot_config", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config\nnodes\nget_snapshot_config\nGet snapshot configuration\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "title": "PUT /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config", + "section": "nodes", + "summary": "update_snapshot_config", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/config\nnodes\nupdate_snapshot_config\nUpdate snapshot metadata.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\ndescription string A textual description or comment.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "title": "POST /nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback", + "section": "nodes", + "summary": "rollback", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/snapshot/{snapname}/rollback\nnodes\nrollback\nRollback VM state to specified snapshot.\nnode string The cluster node name.\nsnapname string The name of the snapshot.\nvmid integer The (unique) ID of the VM.\nstart boolean Whether the VM should get started after rolling back successfully. (Note: VMs will be automatically started if the snapshot includes RAM.)\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\ncheckpoint\nbackup point" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/spiceproxy", + "title": "POST /nodes/{node}/qemu/{vmid}/spiceproxy", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/spiceproxy", + "section": "nodes", + "summary": "spiceproxy", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/spiceproxy\nnodes\nspiceproxy\nReturns a SPICE configuration to connect to the VM.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nproxy string 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).\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/status", + "title": "GET /nodes/{node}/qemu/{vmid}/status", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/status", + "section": "nodes", + "summary": "vmcmdidx", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/status\nnodes\nvmcmdidx\nDirectory index\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/status/current", + "title": "GET /nodes/{node}/qemu/{vmid}/status/current", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/status/current", + "section": "nodes", + "summary": "vm_status", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/status/current\nnodes\nvm_status\nGet virtual machine status.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/reboot", + "title": "POST /nodes/{node}/qemu/{vmid}/status/reboot", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/reboot", + "section": "nodes", + "summary": "vm_reboot", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/reboot\nnodes\nvm_reboot\nReboot the VM by shutting it down, and starting it again. Applies pending changes.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ntimeout integer Wait maximal timeout seconds for the shutdown.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/reset", + "title": "POST /nodes/{node}/qemu/{vmid}/status/reset", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/reset", + "section": "nodes", + "summary": "vm_reset", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/reset\nnodes\nvm_reset\nReset virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/resume", + "title": "POST /nodes/{node}/qemu/{vmid}/status/resume", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/resume", + "section": "nodes", + "summary": "vm_resume", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/resume\nnodes\nvm_resume\nResume virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nnocheck boolean\nskiplock boolean Ignore locks - only root is allowed to use this option.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/shutdown", + "title": "POST /nodes/{node}/qemu/{vmid}/status/shutdown", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/shutdown", + "section": "nodes", + "summary": "vm_shutdown", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/shutdown\nnodes\nvm_shutdown\nShutdown 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.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforceStop boolean Make sure the VM stops.\nkeepActive boolean Do not deactivate storage volumes.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ntimeout integer Wait maximal timeout seconds.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nshutdown\ngraceful stop" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/start", + "title": "POST /nodes/{node}/qemu/{vmid}/status/start", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/start", + "section": "nodes", + "summary": "vm_start", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/start\nnodes\nvm_start\nStart virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nforce-cpu string Override QEMU's -cpu argument with the given string.\nmachine string Specify the QEMU machine.\nmigratedfrom string The cluster node name.\nmigration_network string CIDR of the (sub) network that is used for migration.\nmigration_type string Migration traffic is encrypted using an SSH tunnel by default. On secure, completely private networks this can be disabled to increase performance. secure insecure\nnets-host-mtu string 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.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nstateuri string Some command save/restore state from this location.\ntargetstorage string 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.\ntimeout integer Wait maximal timeout seconds.\nwith-conntrack-state boolean Whether to migrate conntrack entries for running VMs.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstart\nboot\npower on\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstart\nboot\npower on" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/stop", + "title": "POST /nodes/{node}/qemu/{vmid}/status/stop", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/stop", + "section": "nodes", + "summary": "vm_stop", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/stop\nnodes\nvm_stop\nStop 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.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nkeepActive boolean Do not deactivate storage volumes.\nmigratedfrom string The cluster node name.\noverrule-shutdown boolean Try to abort active 'qmshutdown' tasks before stopping.\nskiplock boolean Ignore locks - only root is allowed to use this option.\ntimeout integer Wait maximal timeout seconds.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nstop\nforce stop\npower off" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/status/suspend", + "title": "POST /nodes/{node}/qemu/{vmid}/status/suspend", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/status/suspend", + "section": "nodes", + "summary": "vm_suspend", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/status/suspend\nnodes\nvm_suspend\nSuspend virtual machine.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nskiplock boolean Ignore locks - only root is allowed to use this option.\nstatestorage string The storage for the VM state\ntodisk boolean If set, suspends the VM to disk. Will be resumed on next VM start.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/template", + "title": "POST /nodes/{node}/qemu/{vmid}/template", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/template", + "section": "nodes", + "summary": "template", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/template\nnodes\ntemplate\nCreate a Template.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ndisk string If you want to convert only 1 disk to base image. 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\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/termproxy", + "title": "POST /nodes/{node}/qemu/{vmid}/termproxy", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/termproxy", + "section": "nodes", + "summary": "termproxy", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/termproxy\nnodes\ntermproxy\nCreates a TCP proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nserial string opens a serial terminal (defaults to display) serial0 serial1 serial2 serial3\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "PUT /nodes/{node}/qemu/{vmid}/unlink", + "title": "PUT /nodes/{node}/qemu/{vmid}/unlink", + "method": "PUT", + "path": "/nodes/{node}/qemu/{vmid}/unlink", + "section": "nodes", + "summary": "unlink", + "searchText": "PUT\n/nodes/{node}/qemu/{vmid}/unlink\nnodes\nunlink\nUnlink/delete disk images.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nidlist string A list of disk IDs you want to delete.\nforce boolean 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.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "POST /nodes/{node}/qemu/{vmid}/vncproxy", + "title": "POST /nodes/{node}/qemu/{vmid}/vncproxy", + "method": "POST", + "path": "/nodes/{node}/qemu/{vmid}/vncproxy", + "section": "nodes", + "summary": "vncproxy", + "searchText": "POST\n/nodes/{node}/qemu/{vmid}/vncproxy\nnodes\nvncproxy\nCreates a TCP VNC proxy connections.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\ngenerate-password boolean Deprecated, do not use. Password is generated when required.\nwebsocket boolean Prepare for websocket upgrade (only required when using serial terminal, otherwise upgrade is always possible).\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/qemu/{vmid}/vncwebsocket", + "title": "GET /nodes/{node}/qemu/{vmid}/vncwebsocket", + "method": "GET", + "path": "/nodes/{node}/qemu/{vmid}/vncwebsocket", + "section": "nodes", + "summary": "vncwebsocket", + "searchText": "GET\n/nodes/{node}/qemu/{vmid}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nvmid integer The (unique) ID of the VM.\nport integer Port number returned by previous vncproxy call.\nvncticket string Ticket from previous call to vncproxy.\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id\nvm\nvirtual machine\nkvm guest\nguest id\nvm id\ncontainer id" + }, + { + "id": "GET /nodes/{node}/query-oci-repo-tags", + "title": "GET /nodes/{node}/query-oci-repo-tags", + "method": "GET", + "path": "/nodes/{node}/query-oci-repo-tags", + "section": "nodes", + "summary": "query_oci_repo_tags", + "searchText": "GET\n/nodes/{node}/query-oci-repo-tags\nnodes\nquery_oci_repo_tags\nList all tags for an OCI repository reference.\nnode string The cluster node name.\nreference string The reference to the repository to query tags from." + }, + { + "id": "GET /nodes/{node}/query-url-metadata", + "title": "GET /nodes/{node}/query-url-metadata", + "method": "GET", + "path": "/nodes/{node}/query-url-metadata", + "section": "nodes", + "summary": "query_url_metadata", + "searchText": "GET\n/nodes/{node}/query-url-metadata\nnodes\nquery_url_metadata\nQuery metadata of an URL: file size, file name and mime type.\nnode string The cluster node name.\nurl string The URL to query the metadata from.\nverify-certificates boolean If false, no SSL/TLS certificates will be verified." + }, + { + "id": "GET /nodes/{node}/replication", + "title": "GET /nodes/{node}/replication", + "method": "GET", + "path": "/nodes/{node}/replication", + "section": "nodes", + "summary": "status", + "searchText": "GET\n/nodes/{node}/replication\nnodes\nstatus\nList status of all replication jobs on this node.\nnode string The cluster node name.\nguest integer Only list replication jobs for this guest." + }, + { + "id": "GET /nodes/{node}/replication/{id}", + "title": "GET /nodes/{node}/replication/{id}", + "method": "GET", + "path": "/nodes/{node}/replication/{id}", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/replication/{id}\nnodes\nindex\nDirectory index.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/replication/{id}/log", + "title": "GET /nodes/{node}/replication/{id}/log", + "method": "GET", + "path": "/nodes/{node}/replication/{id}/log", + "section": "nodes", + "summary": "read_job_log", + "searchText": "GET\n/nodes/{node}/replication/{id}/log\nnodes\nread_job_log\nRead replication job log.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name.\nlimit integer\nstart integer" + }, + { + "id": "POST /nodes/{node}/replication/{id}/schedule_now", + "title": "POST /nodes/{node}/replication/{id}/schedule_now", + "method": "POST", + "path": "/nodes/{node}/replication/{id}/schedule_now", + "section": "nodes", + "summary": "schedule_now", + "searchText": "POST\n/nodes/{node}/replication/{id}/schedule_now\nnodes\nschedule_now\nSchedule replication job to start as soon as possible.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/replication/{id}/status", + "title": "GET /nodes/{node}/replication/{id}/status", + "method": "GET", + "path": "/nodes/{node}/replication/{id}/status", + "section": "nodes", + "summary": "job_status", + "searchText": "GET\n/nodes/{node}/replication/{id}/status\nnodes\njob_status\nGet replication job status.\nid string Replication Job ID. The ID is composed of a Guest ID and a job number, separated by a hyphen, i.e. '-'.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/report", + "title": "GET /nodes/{node}/report", + "method": "GET", + "path": "/nodes/{node}/report", + "section": "nodes", + "summary": "report", + "searchText": "GET\n/nodes/{node}/report\nnodes\nreport\nGather various systems information about a node\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/rrd", + "title": "GET /nodes/{node}/rrd", + "method": "GET", + "path": "/nodes/{node}/rrd", + "section": "nodes", + "summary": "rrd", + "searchText": "GET\n/nodes/{node}/rrd\nnodes\nrrd\nRead node RRD statistics (returns PNG)\nnode string The cluster node name.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year decade\ncf string The RRD consolidation function AVERAGE MAX" + }, + { + "id": "GET /nodes/{node}/rrddata", + "title": "GET /nodes/{node}/rrddata", + "method": "GET", + "path": "/nodes/{node}/rrddata", + "section": "nodes", + "summary": "rrddata", + "searchText": "GET\n/nodes/{node}/rrddata\nnodes\nrrddata\nRead node RRD statistics\nnode string The cluster node name.\ntimeframe string Specify the time frame you are interested in. hour day week month year decade\ncf string The RRD consolidation function AVERAGE MAX" + }, + { + "id": "GET /nodes/{node}/scan", + "title": "GET /nodes/{node}/scan", + "method": "GET", + "path": "/nodes/{node}/scan", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/scan\nnodes\nindex\nIndex of available scan methods\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/scan/cifs", + "title": "GET /nodes/{node}/scan/cifs", + "method": "GET", + "path": "/nodes/{node}/scan/cifs", + "section": "nodes", + "summary": "cifsscan", + "searchText": "GET\n/nodes/{node}/scan/cifs\nnodes\ncifsscan\nScan remote CIFS server.\nnode string The cluster node name.\nserver string The server address (name or IP).\ndomain string SMB domain (Workgroup).\npassword string User password.\nusername string User name." + }, + { + "id": "GET /nodes/{node}/scan/iscsi", + "title": "GET /nodes/{node}/scan/iscsi", + "method": "GET", + "path": "/nodes/{node}/scan/iscsi", + "section": "nodes", + "summary": "iscsiscan", + "searchText": "GET\n/nodes/{node}/scan/iscsi\nnodes\niscsiscan\nScan remote iSCSI server.\nnode string The cluster node name.\nportal string The iSCSI portal (IP or DNS name with optional port)." + }, + { + "id": "GET /nodes/{node}/scan/lvm", + "title": "GET /nodes/{node}/scan/lvm", + "method": "GET", + "path": "/nodes/{node}/scan/lvm", + "section": "nodes", + "summary": "lvmscan", + "searchText": "GET\n/nodes/{node}/scan/lvm\nnodes\nlvmscan\nList local LVM volume groups.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/scan/lvmthin", + "title": "GET /nodes/{node}/scan/lvmthin", + "method": "GET", + "path": "/nodes/{node}/scan/lvmthin", + "section": "nodes", + "summary": "lvmthinscan", + "searchText": "GET\n/nodes/{node}/scan/lvmthin\nnodes\nlvmthinscan\nList local LVM Thin Pools.\nnode string The cluster node name.\nvg string" + }, + { + "id": "GET /nodes/{node}/scan/nfs", + "title": "GET /nodes/{node}/scan/nfs", + "method": "GET", + "path": "/nodes/{node}/scan/nfs", + "section": "nodes", + "summary": "nfsscan", + "searchText": "GET\n/nodes/{node}/scan/nfs\nnodes\nnfsscan\nScan remote NFS server.\nnode string The cluster node name.\nserver string The server address (name or IP)." + }, + { + "id": "GET /nodes/{node}/scan/pbs", + "title": "GET /nodes/{node}/scan/pbs", + "method": "GET", + "path": "/nodes/{node}/scan/pbs", + "section": "nodes", + "summary": "pbsscan", + "searchText": "GET\n/nodes/{node}/scan/pbs\nnodes\npbsscan\nScan remote Proxmox Backup Server.\nnode string The cluster node name.\npassword string User password or API token secret.\nserver string The server address (name or IP).\nusername string User-name or API token-ID.\nfingerprint string Certificate SHA 256 fingerprint.\nport integer Optional port." + }, + { + "id": "GET /nodes/{node}/scan/zfs", + "title": "GET /nodes/{node}/scan/zfs", + "method": "GET", + "path": "/nodes/{node}/scan/zfs", + "section": "nodes", + "summary": "zfsscan", + "searchText": "GET\n/nodes/{node}/scan/zfs\nnodes\nzfsscan\nScan zfs pool list on local node.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn", + "title": "GET /nodes/{node}/sdn", + "method": "GET", + "path": "/nodes/{node}/sdn", + "section": "nodes", + "summary": "sdnindex", + "searchText": "GET\n/nodes/{node}/sdn\nnodes\nsdnindex\nSDN index.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}", + "title": "GET /nodes/{node}/sdn/fabrics/{fabric}", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}", + "section": "nodes", + "summary": "diridx", + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}\nnodes\ndiridx\nDirectory index for SDN fabric status.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}/interfaces", + "title": "GET /nodes/{node}/sdn/fabrics/{fabric}/interfaces", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}/interfaces", + "section": "nodes", + "summary": "interfaces", + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}/interfaces\nnodes\ninterfaces\nGet all interfaces for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}/neighbors", + "title": "GET /nodes/{node}/sdn/fabrics/{fabric}/neighbors", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}/neighbors", + "section": "nodes", + "summary": "neighbors", + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}/neighbors\nnodes\nneighbors\nGet all neighbors for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/fabrics/{fabric}/routes", + "title": "GET /nodes/{node}/sdn/fabrics/{fabric}/routes", + "method": "GET", + "path": "/nodes/{node}/sdn/fabrics/{fabric}/routes", + "section": "nodes", + "summary": "routes", + "searchText": "GET\n/nodes/{node}/sdn/fabrics/{fabric}/routes\nnodes\nroutes\nGet all routes for a fabric.\nfabric string Identifier for SDN fabrics\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/vnets/{vnet}", + "title": "GET /nodes/{node}/sdn/vnets/{vnet}", + "method": "GET", + "path": "/nodes/{node}/sdn/vnets/{vnet}", + "section": "nodes", + "summary": "diridx", + "searchText": "GET\n/nodes/{node}/sdn/vnets/{vnet}\nnodes\ndiridx\ndiridx\nnode string The cluster node name.\nvnet string The SDN vnet object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/vnets/{vnet}/mac-vrf", + "title": "GET /nodes/{node}/sdn/vnets/{vnet}/mac-vrf", + "method": "GET", + "path": "/nodes/{node}/sdn/vnets/{vnet}/mac-vrf", + "section": "nodes", + "summary": "mac-vrf", + "searchText": "GET\n/nodes/{node}/sdn/vnets/{vnet}/mac-vrf\nnodes\nmac-vrf\nGet the MAC VRF for a VNet in an EVPN zone.\nnode string The cluster node name.\nvnet string The SDN vnet object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/zones", + "title": "GET /nodes/{node}/sdn/zones", + "method": "GET", + "path": "/nodes/{node}/sdn/zones", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/sdn/zones\nnodes\nindex\nGet status for all zones.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}", + "title": "GET /nodes/{node}/sdn/zones/{zone}", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}", + "section": "nodes", + "summary": "diridx", + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}\nnodes\ndiridx\nDirectory index for SDN zone status.\nnode string The cluster node name.\nzone string The SDN zone object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}/bridges", + "title": "GET /nodes/{node}/sdn/zones/{zone}/bridges", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}/bridges", + "section": "nodes", + "summary": "bridges", + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}/bridges\nnodes\nbridges\nGet a list of all bridges (vnets) that are part of a zone, as well as the ports that are members of that bridge.\nnode string The cluster node name.\nzone string zone name or \"localnetwork\"" + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}/content", + "title": "GET /nodes/{node}/sdn/zones/{zone}/content", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}/content", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}/content\nnodes\nindex\nList zone content.\nnode string The cluster node name.\nzone string The SDN zone object identifier." + }, + { + "id": "GET /nodes/{node}/sdn/zones/{zone}/ip-vrf", + "title": "GET /nodes/{node}/sdn/zones/{zone}/ip-vrf", + "method": "GET", + "path": "/nodes/{node}/sdn/zones/{zone}/ip-vrf", + "section": "nodes", + "summary": "ip-vrf", + "searchText": "GET\n/nodes/{node}/sdn/zones/{zone}/ip-vrf\nnodes\nip-vrf\nGet the IP VRF of an EVPN zone.\nnode string The cluster node name.\nzone string Name of an EVPN zone." + }, + { + "id": "GET /nodes/{node}/services", + "title": "GET /nodes/{node}/services", + "method": "GET", + "path": "/nodes/{node}/services", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/services\nnodes\nindex\nService list.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/services/{service}", + "title": "GET /nodes/{node}/services/{service}", + "method": "GET", + "path": "/nodes/{node}/services/{service}", + "section": "nodes", + "summary": "srvcmdidx", + "searchText": "GET\n/nodes/{node}/services/{service}\nnodes\nsrvcmdidx\nDirectory index\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/reload", + "title": "POST /nodes/{node}/services/{service}/reload", + "method": "POST", + "path": "/nodes/{node}/services/{service}/reload", + "section": "nodes", + "summary": "service_reload", + "searchText": "POST\n/nodes/{node}/services/{service}/reload\nnodes\nservice_reload\nReload service. Falls back to restart if service cannot be reloaded.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/restart", + "title": "POST /nodes/{node}/services/{service}/restart", + "method": "POST", + "path": "/nodes/{node}/services/{service}/restart", + "section": "nodes", + "summary": "service_restart", + "searchText": "POST\n/nodes/{node}/services/{service}/restart\nnodes\nservice_restart\nHard restart service. Use reload if you want to reduce interruptions.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/start", + "title": "POST /nodes/{node}/services/{service}/start", + "method": "POST", + "path": "/nodes/{node}/services/{service}/start", + "section": "nodes", + "summary": "service_start", + "searchText": "POST\n/nodes/{node}/services/{service}/start\nnodes\nservice_start\nStart service.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "GET /nodes/{node}/services/{service}/state", + "title": "GET /nodes/{node}/services/{service}/state", + "method": "GET", + "path": "/nodes/{node}/services/{service}/state", + "section": "nodes", + "summary": "service_state", + "searchText": "GET\n/nodes/{node}/services/{service}/state\nnodes\nservice_state\nRead service properties\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/services/{service}/stop", + "title": "POST /nodes/{node}/services/{service}/stop", + "method": "POST", + "path": "/nodes/{node}/services/{service}/stop", + "section": "nodes", + "summary": "service_stop", + "searchText": "POST\n/nodes/{node}/services/{service}/stop\nnodes\nservice_stop\nStop service.\nnode string The cluster node name.\nservice string Service ID 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" + }, + { + "id": "POST /nodes/{node}/spiceshell", + "title": "POST /nodes/{node}/spiceshell", + "method": "POST", + "path": "/nodes/{node}/spiceshell", + "section": "nodes", + "summary": "spiceshell", + "searchText": "POST\n/nodes/{node}/spiceshell\nnodes\nspiceshell\nCreates a SPICE shell.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings.\nproxy string 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)." + }, + { + "id": "POST /nodes/{node}/startall", + "title": "POST /nodes/{node}/startall", + "method": "POST", + "path": "/nodes/{node}/startall", + "section": "nodes", + "summary": "startall", + "searchText": "POST\n/nodes/{node}/startall\nnodes\nstartall\nStart all VMs and containers located on this node (by default only those with onboot=1).\nnode string The cluster node name.\nforce boolean Issue start command even if virtual guest have 'onboot' not set or set to off.\nmax-workers integer 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.\nvms string Only consider guests from this comma separated list of VMIDs." + }, + { + "id": "GET /nodes/{node}/status", + "title": "GET /nodes/{node}/status", + "method": "GET", + "path": "/nodes/{node}/status", + "section": "nodes", + "summary": "status", + "searchText": "GET\n/nodes/{node}/status\nnodes\nstatus\nRead node status\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/status", + "title": "POST /nodes/{node}/status", + "method": "POST", + "path": "/nodes/{node}/status", + "section": "nodes", + "summary": "node_cmd", + "searchText": "POST\n/nodes/{node}/status\nnodes\nnode_cmd\nReboot or shutdown a node.\nnode string The cluster node name.\ncommand string Specify the command. reboot shutdown" + }, + { + "id": "POST /nodes/{node}/stopall", + "title": "POST /nodes/{node}/stopall", + "method": "POST", + "path": "/nodes/{node}/stopall", + "section": "nodes", + "summary": "stopall", + "searchText": "POST\n/nodes/{node}/stopall\nnodes\nstopall\nStop all VMs and Containers.\nnode string The cluster node name.\nforce-stop boolean Force a hard-stop after the timeout.\nmax-workers integer 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.\ntimeout integer Timeout for each guest shutdown task. Depending on `force-stop`, the shutdown gets then simply aborted or a hard-stop is forced.\nvms string Only consider Guests with these IDs." + }, + { + "id": "GET /nodes/{node}/storage", + "title": "GET /nodes/{node}/storage", + "method": "GET", + "path": "/nodes/{node}/storage", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/storage\nnodes\nindex\nGet status for all datastores.\nnode string The cluster node name.\ncontent string Only list stores which support this content type.\nenabled boolean Only list stores which are enabled (not disabled in config).\nformat boolean Include information about formats\nstorage string Only list status for specified storage\ntarget string If target is different to 'node', we only lists shared storages which content is accessible on this 'node' and the specified 'target' node.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}", + "title": "GET /nodes/{node}/storage/{storage}", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}", + "section": "nodes", + "summary": "diridx", + "searchText": "GET\n/nodes/{node}/storage/{storage}\nnodes\ndiridx\ndiridx\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/content", + "title": "GET /nodes/{node}/storage/{storage}/content", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/content", + "section": "nodes", + "summary": "index", + "searchText": "GET\n/nodes/{node}/storage/{storage}/content\nnodes\nindex\nList storage content.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Only list content of this type.\nvmid integer Only list images for this VM\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/content", + "title": "POST /nodes/{node}/storage/{storage}/content", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/content", + "section": "nodes", + "summary": "create", + "searchText": "POST\n/nodes/{node}/storage/{storage}/content\nnodes\ncreate\nAllocate disk images.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilename string The name of the file to create.\nsize string Size in kilobyte (1024 bytes). Optional suffixes 'M' (megabyte, 1024K) and 'G' (gigabyte, 1024M)\nvmid integer Specify owner VM\nformat string Format of the image. raw qcow2 subvol vmdk\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "DELETE /nodes/{node}/storage/{storage}/content/{volume}", + "title": "DELETE /nodes/{node}/storage/{storage}/content/{volume}", + "method": "DELETE", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "delete", + "searchText": "DELETE\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ndelete\nDelete volume\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\ndelay integer Time to wait for the task to finish. We return 'null' if the task finish within that time.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/content/{volume}", + "title": "GET /nodes/{node}/storage/{storage}/content/{volume}", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "info", + "searchText": "GET\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ninfo\nGet volume attributes\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/content/{volume}", + "title": "POST /nodes/{node}/storage/{storage}/content/{volume}", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "copy", + "searchText": "POST\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\ncopy\nCopy a volume. This is experimental code - do not use.\nnode string The cluster node name.\nvolume string Source volume identifier\nstorage string The storage identifier.\ntarget string Target volume identifier\ntarget_node string Target node. Default is local node.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "PUT /nodes/{node}/storage/{storage}/content/{volume}", + "title": "PUT /nodes/{node}/storage/{storage}/content/{volume}", + "method": "PUT", + "path": "/nodes/{node}/storage/{storage}/content/{volume}", + "section": "nodes", + "summary": "updateattributes", + "searchText": "PUT\n/nodes/{node}/storage/{storage}/content/{volume}\nnodes\nupdateattributes\nUpdate volume attributes\nnode string The cluster node name.\nvolume string Volume identifier\nstorage string The storage identifier.\nnotes string The new notes.\nprotected boolean Protection status. Currently only supported for backups.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/download-url", + "title": "POST /nodes/{node}/storage/{storage}/download-url", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/download-url", + "section": "nodes", + "summary": "download_url", + "searchText": "POST\n/nodes/{node}/storage/{storage}/download-url\nnodes\ndownload_url\nDownload templates, ISO images, OVAs and VM images by using an URL.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Content type. iso vztmpl import\nfilename string The name of the file to create. Caution: This will be normalized!\nurl string The URL to download the file from.\nchecksum string The expected checksum of the file.\nchecksum-algorithm string The algorithm to calculate the checksum of the file. md5 sha1 sha224 sha256 sha384 sha512\ncompression string Decompress the downloaded file using the specified compression algorithm.\nverify-certificates boolean If false, no SSL/TLS certificates will be verified.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/file-restore/download", + "title": "GET /nodes/{node}/storage/{storage}/file-restore/download", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/file-restore/download", + "section": "nodes", + "summary": "download", + "searchText": "GET\n/nodes/{node}/storage/{storage}/file-restore/download\nnodes\ndownload\nExtract a file or directory (as zip archive) from a PBS backup.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilepath string base64-path to the directory or file to download.\nvolume string Backup volume ID or name. Currently only PBS snapshots are supported.\ntar boolean Download dirs as 'tar.zst' instead of 'zip'.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/file-restore/list", + "title": "GET /nodes/{node}/storage/{storage}/file-restore/list", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/file-restore/list", + "section": "nodes", + "summary": "list", + "searchText": "GET\n/nodes/{node}/storage/{storage}/file-restore/list\nnodes\nlist\nList files and directories for single file restore under the given path.\nnode string The cluster node name.\nstorage string The storage identifier.\nfilepath string base64-path to the directory or file being listed, or \"/\".\nvolume string Backup volume ID or name. Currently only PBS snapshots are supported.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/identity", + "title": "GET /nodes/{node}/storage/{storage}/identity", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/identity", + "section": "nodes", + "summary": "identity", + "searchText": "GET\n/nodes/{node}/storage/{storage}/identity\nnodes\nidentity\nReturn identity information for this storage instance.\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/import-metadata", + "title": "GET /nodes/{node}/storage/{storage}/import-metadata", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/import-metadata", + "section": "nodes", + "summary": "get_import_metadata", + "searchText": "GET\n/nodes/{node}/storage/{storage}/import-metadata\nnodes\nget_import_metadata\nGet the base parameters for creating a guest which imports data from a foreign importable guest, like an ESXi VM\nnode string The cluster node name.\nstorage string The storage identifier.\nvolume string Volume identifier for the guest archive/entry.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/oci-registry-pull", + "title": "POST /nodes/{node}/storage/{storage}/oci-registry-pull", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/oci-registry-pull", + "section": "nodes", + "summary": "oci_registry_pull", + "searchText": "POST\n/nodes/{node}/storage/{storage}/oci-registry-pull\nnodes\noci_registry_pull\nPull an OCI image from a registry.\nnode string The cluster node name.\nstorage string The storage identifier.\nreference string The reference to the OCI image to download.\nfilename string Custom destination file name of the OCI image. Caution: This will be normalized!\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "DELETE /nodes/{node}/storage/{storage}/prunebackups", + "title": "DELETE /nodes/{node}/storage/{storage}/prunebackups", + "method": "DELETE", + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "section": "nodes", + "summary": "delete", + "searchText": "DELETE\n/nodes/{node}/storage/{storage}/prunebackups\nnodes\ndelete\nPrune backups. Only those using the standard naming scheme are considered.\nnode string The cluster node name.\nstorage string The storage identifier.\nprune-backups string Use these retention options instead of those from the storage configuration.\ntype string Either 'qemu' or 'lxc'. Only consider backups for guests of this type. qemu lxc\nvmid integer Only prune backups for this VM.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/prunebackups", + "title": "GET /nodes/{node}/storage/{storage}/prunebackups", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/prunebackups", + "section": "nodes", + "summary": "dryrun", + "searchText": "GET\n/nodes/{node}/storage/{storage}/prunebackups\nnodes\ndryrun\nGet 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.\nnode string The cluster node name.\nstorage string The storage identifier.\nprune-backups string Use these retention options instead of those from the storage configuration.\ntype string Either 'qemu' or 'lxc'. Only consider backups for guests of this type. qemu lxc\nvmid integer Only consider backups for this guest.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/rrd", + "title": "GET /nodes/{node}/storage/{storage}/rrd", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/rrd", + "section": "nodes", + "summary": "rrd", + "searchText": "GET\n/nodes/{node}/storage/{storage}/rrd\nnodes\nrrd\nRead storage RRD statistics (returns PNG).\nnode string The cluster node name.\nstorage string The storage identifier.\nds string The list of datasources you want to display.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/rrddata", + "title": "GET /nodes/{node}/storage/{storage}/rrddata", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/rrddata", + "section": "nodes", + "summary": "rrddata", + "searchText": "GET\n/nodes/{node}/storage/{storage}/rrddata\nnodes\nrrddata\nRead storage RRD statistics.\nnode string The cluster node name.\nstorage string The storage identifier.\ntimeframe string Specify the time frame you are interested in. hour day week month year\ncf string The RRD consolidation function AVERAGE MAX\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /nodes/{node}/storage/{storage}/status", + "title": "GET /nodes/{node}/storage/{storage}/status", + "method": "GET", + "path": "/nodes/{node}/storage/{storage}/status", + "section": "nodes", + "summary": "read_status", + "searchText": "GET\n/nodes/{node}/storage/{storage}/status\nnodes\nread_status\nRead storage status.\nnode string The cluster node name.\nstorage string The storage identifier.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "POST /nodes/{node}/storage/{storage}/upload", + "title": "POST /nodes/{node}/storage/{storage}/upload", + "method": "POST", + "path": "/nodes/{node}/storage/{storage}/upload", + "section": "nodes", + "summary": "upload", + "searchText": "POST\n/nodes/{node}/storage/{storage}/upload\nnodes\nupload\nUpload templates, ISO images, OVAs and VM images.\nnode string The cluster node name.\nstorage string The storage identifier.\ncontent string Content type. iso vztmpl import\nfilename string The name of the file to create. Caution: This will be normalized!\nchecksum string The expected checksum of the file.\nchecksum-algorithm string The algorithm to calculate the checksum of the file. md5 sha1 sha224 sha256 sha384 sha512\ntmpfilename string 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.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "DELETE /nodes/{node}/subscription", + "title": "DELETE /nodes/{node}/subscription", + "method": "DELETE", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "delete", + "searchText": "DELETE\n/nodes/{node}/subscription\nnodes\ndelete\nDelete subscription key of this node.\nnode string The cluster node name." + }, + { + "id": "GET /nodes/{node}/subscription", + "title": "GET /nodes/{node}/subscription", + "method": "GET", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "get", + "searchText": "GET\n/nodes/{node}/subscription\nnodes\nget\nRead subscription info.\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/subscription", + "title": "POST /nodes/{node}/subscription", + "method": "POST", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "update", + "searchText": "POST\n/nodes/{node}/subscription\nnodes\nupdate\nUpdate subscription info.\nnode string The cluster node name.\nforce boolean Always connect to server, even if local cache is still valid." + }, + { + "id": "PUT /nodes/{node}/subscription", + "title": "PUT /nodes/{node}/subscription", + "method": "PUT", + "path": "/nodes/{node}/subscription", + "section": "nodes", + "summary": "set", + "searchText": "PUT\n/nodes/{node}/subscription\nnodes\nset\nSet subscription key.\nnode string The cluster node name.\nkey string Proxmox VE subscription key" + }, + { + "id": "POST /nodes/{node}/suspendall", + "title": "POST /nodes/{node}/suspendall", + "method": "POST", + "path": "/nodes/{node}/suspendall", + "section": "nodes", + "summary": "suspendall", + "searchText": "POST\n/nodes/{node}/suspendall\nnodes\nsuspendall\nSuspend all VMs.\nnode string The cluster node name.\nmax-workers integer 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.\nvms string Only consider Guests with these IDs." + }, + { + "id": "GET /nodes/{node}/syslog", + "title": "GET /nodes/{node}/syslog", + "method": "GET", + "path": "/nodes/{node}/syslog", + "section": "nodes", + "summary": "syslog", + "searchText": "GET\n/nodes/{node}/syslog\nnodes\nsyslog\nRead system log\nnode string The cluster node name.\nlimit integer\nservice string Service ID\nsince string Display all log since this date-time string.\nstart integer\nuntil string Display all log until this date-time string." + }, + { + "id": "GET /nodes/{node}/tasks", + "title": "GET /nodes/{node}/tasks", + "method": "GET", + "path": "/nodes/{node}/tasks", + "section": "nodes", + "summary": "node_tasks", + "searchText": "GET\n/nodes/{node}/tasks\nnodes\nnode_tasks\nRead task list for one node (finished tasks).\nnode string The cluster node name.\nerrors boolean Only list tasks with a status of ERROR.\nlimit integer Only list this number of tasks.\nsince integer Only list tasks since this UNIX epoch.\nsource string List archived, active or all tasks. archive active all\nstart integer List tasks beginning from this offset.\nstatusfilter string List of Task States that should be returned.\ntypefilter string Only list tasks of this type (e.g., vzstart, vzdump).\nuntil integer Only list tasks until this UNIX epoch.\nuserfilter string Only list tasks from this user.\nvmid integer Only list tasks for this VM." + }, + { + "id": "DELETE /nodes/{node}/tasks/{upid}", + "title": "DELETE /nodes/{node}/tasks/{upid}", + "method": "DELETE", + "path": "/nodes/{node}/tasks/{upid}", + "section": "nodes", + "summary": "stop_task", + "searchText": "DELETE\n/nodes/{node}/tasks/{upid}\nnodes\nstop_task\nStop a task.\nnode string The cluster node name.\nupid string" + }, + { + "id": "GET /nodes/{node}/tasks/{upid}", + "title": "GET /nodes/{node}/tasks/{upid}", + "method": "GET", + "path": "/nodes/{node}/tasks/{upid}", + "section": "nodes", + "summary": "upid_index", + "searchText": "GET\n/nodes/{node}/tasks/{upid}\nnodes\nupid_index\nupid_index\nnode string The cluster node name.\nupid string" + }, + { + "id": "GET /nodes/{node}/tasks/{upid}/log", + "title": "GET /nodes/{node}/tasks/{upid}/log", + "method": "GET", + "path": "/nodes/{node}/tasks/{upid}/log", + "section": "nodes", + "summary": "read_task_log", + "searchText": "GET\n/nodes/{node}/tasks/{upid}/log\nnodes\nread_task_log\nRead task log.\nnode string The cluster node name.\nupid string The task's unique ID.\ndownload boolean Whether the tasklog file should be downloaded. This parameter can't be used in conjunction with other parameters\nlimit integer The number of lines to read from the tasklog.\nstart integer Start at this line when reading the tasklog" + }, + { + "id": "GET /nodes/{node}/tasks/{upid}/status", + "title": "GET /nodes/{node}/tasks/{upid}/status", + "method": "GET", + "path": "/nodes/{node}/tasks/{upid}/status", + "section": "nodes", + "summary": "read_task_status", + "searchText": "GET\n/nodes/{node}/tasks/{upid}/status\nnodes\nread_task_status\nRead task status.\nnode string The cluster node name.\nupid string The task's unique ID." + }, + { + "id": "POST /nodes/{node}/termproxy", + "title": "POST /nodes/{node}/termproxy", + "method": "POST", + "path": "/nodes/{node}/termproxy", + "section": "nodes", + "summary": "termproxy", + "searchText": "POST\n/nodes/{node}/termproxy\nnodes\ntermproxy\nCreates a VNC Shell proxy.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings." + }, + { + "id": "GET /nodes/{node}/time", + "title": "GET /nodes/{node}/time", + "method": "GET", + "path": "/nodes/{node}/time", + "section": "nodes", + "summary": "time", + "searchText": "GET\n/nodes/{node}/time\nnodes\ntime\nRead server time and time zone settings.\nnode string The cluster node name." + }, + { + "id": "PUT /nodes/{node}/time", + "title": "PUT /nodes/{node}/time", + "method": "PUT", + "path": "/nodes/{node}/time", + "section": "nodes", + "summary": "set_timezone", + "searchText": "PUT\n/nodes/{node}/time\nnodes\nset_timezone\nSet time zone.\nnode string The cluster node name.\ntimezone string Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names." + }, + { + "id": "GET /nodes/{node}/version", + "title": "GET /nodes/{node}/version", + "method": "GET", + "path": "/nodes/{node}/version", + "section": "nodes", + "summary": "version", + "searchText": "GET\n/nodes/{node}/version\nnodes\nversion\nAPI version details\nnode string The cluster node name." + }, + { + "id": "POST /nodes/{node}/vncshell", + "title": "POST /nodes/{node}/vncshell", + "method": "POST", + "path": "/nodes/{node}/vncshell", + "section": "nodes", + "summary": "vncshell", + "searchText": "POST\n/nodes/{node}/vncshell\nnodes\nvncshell\nCreates a VNC Shell proxy.\nnode string The cluster node name.\ncmd string Run specific command or default to login (requires 'root@pam') ceph_install login upgrade\ncmd-opts string Add parameters to a command. Encoded as null terminated strings.\nheight integer sets the height of the console in pixels.\nwebsocket boolean use websocket instead of standard vnc.\nwidth integer sets the width of the console in pixels." + }, + { + "id": "GET /nodes/{node}/vncwebsocket", + "title": "GET /nodes/{node}/vncwebsocket", + "method": "GET", + "path": "/nodes/{node}/vncwebsocket", + "section": "nodes", + "summary": "vncwebsocket", + "searchText": "GET\n/nodes/{node}/vncwebsocket\nnodes\nvncwebsocket\nOpens a websocket for VNC traffic.\nnode string The cluster node name.\nport integer Port number returned by previous 'vncshell' call.\nvncticket string Ticket from previous call to 'vncshell'." + }, + { + "id": "POST /nodes/{node}/vzdump", + "title": "POST /nodes/{node}/vzdump", + "method": "POST", + "path": "/nodes/{node}/vzdump", + "section": "nodes", + "summary": "vzdump", + "searchText": "POST\n/nodes/{node}/vzdump\nnodes\nvzdump\nCreate backup.\nnode string Only run if executed on this node.\nall boolean Backup all known guest systems on this host.\nbwlimit integer Limit I/O bandwidth (in KiB/s).\ncompress string Compress dump file. 0 1 gzip lzo zstd\ndumpdir string Store resulting files to specified directory.\nexclude string Exclude specified guest systems (assumes --all)\nexclude-path array Exclude certain files/directories (shell globs). Paths starting with '/' are anchored to the container's root, other paths match relative to each subdirectory.\nfleecing string Options for backup fleecing (VM only).\nionice integer 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.\njob-id string 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.\nlockwait integer Maximal time to wait for the global lock (minutes).\nmailnotification string Deprecated: use notification targets/matchers instead. Specify when to send a notification mail always failure\nmailto string Deprecated: Use notification targets/matchers instead. Comma-separated list of email addresses or users that should receive email notifications.\nmode string Backup mode. snapshot suspend stop\nnotes-template string 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.\nnotification-mode string 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. auto legacy-sendmail notification-system\npbs-change-detection-mode string PBS mode used to detect file changes and switch encoding format for container backups. legacy data metadata\nperformance string Other performance-related settings.\npigz integer Use pigz instead of gzip when N>0. N=1 uses half of cores, N>1 uses N as thread count.\npool string Backup all known guest systems included in the specified pool.\nprotected boolean If true, mark backup(s) as protected.\nprune-backups string Use these retention options instead of those from the storage configuration.\nquiet boolean Be quiet.\nremove boolean Prune older backups according to 'prune-backups'.\nscript string Use specified hook script.\nstdexcludes boolean Exclude temporary files and logs.\nstdout boolean Write tar to stdout, not to a file.\nstop boolean Stop running backup jobs on this host.\nstopwait integer Maximal time to wait until a guest system is stopped (minutes).\nstorage string Store resulting file to this storage.\ntmpdir string Store temporary files to specified directory.\nvmid string The ID of the guest system you want to backup.\nzstd integer 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." + }, + { + "id": "GET /nodes/{node}/vzdump/defaults", + "title": "GET /nodes/{node}/vzdump/defaults", + "method": "GET", + "path": "/nodes/{node}/vzdump/defaults", + "section": "nodes", + "summary": "defaults", + "searchText": "GET\n/nodes/{node}/vzdump/defaults\nnodes\ndefaults\nGet the currently configured vzdump defaults.\nnode string The cluster node name.\nstorage string The storage identifier." + }, + { + "id": "GET /nodes/{node}/vzdump/extractconfig", + "title": "GET /nodes/{node}/vzdump/extractconfig", + "method": "GET", + "path": "/nodes/{node}/vzdump/extractconfig", + "section": "nodes", + "summary": "extractconfig", + "searchText": "GET\n/nodes/{node}/vzdump/extractconfig\nnodes\nextractconfig\nExtract configuration from vzdump backup archive.\nnode string The cluster node name.\nvolume string Volume identifier" + }, + { + "id": "POST /nodes/{node}/wakeonlan", + "title": "POST /nodes/{node}/wakeonlan", + "method": "POST", + "path": "/nodes/{node}/wakeonlan", + "section": "nodes", + "summary": "wakeonlan", + "searchText": "POST\n/nodes/{node}/wakeonlan\nnodes\nwakeonlan\nTry to wake a node via 'wake on LAN' network packet.\nnode string target node for wake on LAN packet" + }, + { + "id": "DELETE /pools", + "title": "DELETE /pools", + "method": "DELETE", + "path": "/pools", + "section": "pools", + "summary": "delete_pool", + "searchText": "DELETE\n/pools\npools\ndelete_pool\nDelete pool.\npoolid string" + }, + { + "id": "GET /pools", + "title": "GET /pools", + "method": "GET", + "path": "/pools", + "section": "pools", + "summary": "index", + "searchText": "GET\n/pools\npools\nindex\nList pools or get pool configuration.\npoolid string\ntype string qemu lxc storage" + }, + { + "id": "POST /pools", + "title": "POST /pools", + "method": "POST", + "path": "/pools", + "section": "pools", + "summary": "create_pool", + "searchText": "POST\n/pools\npools\ncreate_pool\nCreate new pool.\npoolid string\ncomment string" + }, + { + "id": "PUT /pools", + "title": "PUT /pools", + "method": "PUT", + "path": "/pools", + "section": "pools", + "summary": "update_pool", + "searchText": "PUT\n/pools\npools\nupdate_pool\nUpdate pool.\npoolid string\nallow-move boolean Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.\ncomment string\ndelete boolean Remove the passed VMIDs and/or storage IDs instead of adding them.\nstorage string List of storage IDs to add or remove from this pool.\nvms string List of guest VMIDs to add or remove from this pool." + }, + { + "id": "DELETE /pools/{poolid}", + "title": "DELETE /pools/{poolid}", + "method": "DELETE", + "path": "/pools/{poolid}", + "section": "pools", + "summary": "delete_pool_deprecated", + "searchText": "DELETE\n/pools/{poolid}\npools\ndelete_pool_deprecated\nDelete pool (deprecated, no support for nested pools, use 'DELETE /pools/?poolid={poolid}').\npoolid string" + }, + { + "id": "GET /pools/{poolid}", + "title": "GET /pools/{poolid}", + "method": "GET", + "path": "/pools/{poolid}", + "section": "pools", + "summary": "read_pool", + "searchText": "GET\n/pools/{poolid}\npools\nread_pool\nGet pool configuration (deprecated, no support for nested pools, use 'GET /pools/?poolid={poolid}').\npoolid string\ntype string qemu lxc storage" + }, + { + "id": "PUT /pools/{poolid}", + "title": "PUT /pools/{poolid}", + "method": "PUT", + "path": "/pools/{poolid}", + "section": "pools", + "summary": "update_pool_deprecated", + "searchText": "PUT\n/pools/{poolid}\npools\nupdate_pool_deprecated\nUpdate pool data (deprecated, no support for nested pools - use 'PUT /pools/?poolid={poolid}' instead).\npoolid string\nallow-move boolean Allow adding a guest even if already in another pool. The guest will be removed from its current pool and added to this one.\ncomment string\ndelete boolean Remove the passed VMIDs and/or storage IDs instead of adding them.\nstorage string List of storage IDs to add or remove from this pool.\nvms string List of guest VMIDs to add or remove from this pool." + }, + { + "id": "GET /storage", + "title": "GET /storage", + "method": "GET", + "path": "/storage", + "section": "storage", + "summary": "index", + "searchText": "GET\n/storage\nstorage\nindex\nStorage index.\ntype string Only list storage of specific type btrfs cephfs cifs dir esxi iscsi iscsidirect lvm lvmthin nfs pbs rbd zfs zfspool\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "POST /storage", + "title": "POST /storage", + "method": "POST", + "path": "/storage", + "section": "storage", + "summary": "create", + "searchText": "POST\n/storage\nstorage\ncreate\nCreate a new storage.\nstorage string The storage identifier.\ntype string Storage type. btrfs cephfs cifs dir esxi iscsi iscsidirect lvm lvmthin nfs pbs rbd zfs zfspool\nauthsupported string Authsupported.\nbase string Base volume. This volume is automatically activated.\nblocksize string ZFS block size\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\ncomstar_hg string host group for comstar views\ncomstar_tg string target group for comstar views\ncontent string Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\ncontent-dirs string Overrides for default content type directories.\ncreate-base-path boolean Create the base directory if it doesn't exist.\ncreate-subdirs boolean Populate the directory with the default structure.\ndata-pool string Data Pool (for erasure coding only)\ndatastore string Proxmox Backup Server datastore name.\ndisable boolean Flag to disable the storage.\ndomain string CIFS domain.\nencryption-key string Encryption key. Use 'autogen' to generate one automatically without passphrase.\nexport string NFS export path.\nfingerprint string Certificate SHA 256 fingerprint.\nformat string Default image format. raw qcow2 subvol vmdk\nfs-name string The Ceph filesystem name.\nfuse boolean Mount CephFS through FUSE.\nis_mountpoint string 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.\niscsiprovider string iscsi provider\nkeyring string Client keyring contents (for external clusters).\nkrbd boolean Always access rbd through krbd kernel module.\nlio_tpg string target portal group for Linux LIO targets\nmaster-pubkey string Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.\nmax-protected-backups integer Maximal number of protected backups per guest. Use '-1' for unlimited.\nmkdir boolean 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.\nmonhost string IP addresses of monitors (for external clusters).\nmountpoint string mount point\nnamespace string Namespace.\nnocow boolean 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.\nnodes string List of nodes for which the storage configuration applies.\nnowritecache boolean disable write caching on the target\noptions string NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')\npassword string Password for accessing the share/datastore.\npath string File system path.\npool string Pool.\nport integer 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.\nportal string iSCSI portal (IP or DNS name with optional port).\npreallocation string Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. off metadata falloc full\nprune-backups string 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.\nsaferemove boolean Zero-out data when removing LVs.\nsaferemove_throughput string Wipe throughput (cstream -t parameter value).\nsaferemove-stepsize integer Wipe step size in MiB. It will be capped to the maximum supported by the storage. 1 2 4 8 16 32\nserver string Server IP or DNS name.\nshare string CIFS share.\nshared boolean 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!\nskip-cert-verification boolean Disable TLS certificate verification, only enable on fully trusted networks!\nsmbversion string SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. default 2.0 2.1 3 3.0 3.11\nsnapshot-as-volume-chain boolean Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.\nsparse boolean use sparse volumes\nsubdir string Subdir to mount.\ntagged_only boolean Only list logical volumes tagged with 'pve-vm-ID'.\ntarget string iSCSI target.\nthinpool string LVM thin pool LV name.\nusername string RBD Id.\nvgname string Volume group name.\nzfs-base-path string Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "DELETE /storage/{storage}", + "title": "DELETE /storage/{storage}", + "method": "DELETE", + "path": "/storage/{storage}", + "section": "storage", + "summary": "delete", + "searchText": "DELETE\n/storage/{storage}\nstorage\ndelete\nDelete storage configuration.\nstorage string The storage identifier.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /storage/{storage}", + "title": "GET /storage/{storage}", + "method": "GET", + "path": "/storage/{storage}", + "section": "storage", + "summary": "read", + "searchText": "GET\n/storage/{storage}\nstorage\nread\nRead storage configuration.\nstorage string The storage identifier.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "PUT /storage/{storage}", + "title": "PUT /storage/{storage}", + "method": "PUT", + "path": "/storage/{storage}", + "section": "storage", + "summary": "update", + "searchText": "PUT\n/storage/{storage}\nstorage\nupdate\nUpdate storage configuration.\nstorage string The storage identifier.\nblocksize string ZFS block size\nbwlimit string Set I/O bandwidth limit for various operations (in KiB/s).\ncomstar_hg string host group for comstar views\ncomstar_tg string target group for comstar views\ncontent string Allowed content types.\n\nNOTE: the value 'rootdir' is used for Containers, and value 'images' for VMs.\ncontent-dirs string Overrides for default content type directories.\ncreate-base-path boolean Create the base directory if it doesn't exist.\ncreate-subdirs boolean Populate the directory with the default structure.\ndata-pool string Data Pool (for erasure coding only)\ndelete string A list of settings you want to delete.\ndigest string Prevent changes if current configuration file has a different digest. This can be used to prevent concurrent modifications.\ndisable boolean Flag to disable the storage.\ndomain string CIFS domain.\nencryption-key string Encryption key. Use 'autogen' to generate one automatically without passphrase.\nfingerprint string Certificate SHA 256 fingerprint.\nformat string Default image format. raw qcow2 subvol vmdk\nfs-name string The Ceph filesystem name.\nfuse boolean Mount CephFS through FUSE.\nis_mountpoint string 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.\nkeyring string Client keyring contents (for external clusters).\nkrbd boolean Always access rbd through krbd kernel module.\nlio_tpg string target portal group for Linux LIO targets\nmaster-pubkey string Base64-encoded, PEM-formatted public RSA key. Used to encrypt a copy of the encryption-key which will be added to each encrypted backup.\nmax-protected-backups integer Maximal number of protected backups per guest. Use '-1' for unlimited.\nmkdir boolean 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.\nmonhost string IP addresses of monitors (for external clusters).\nmountpoint string mount point\nnamespace string Namespace.\nnocow boolean 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.\nnodes string List of nodes for which the storage configuration applies.\nnowritecache boolean disable write caching on the target\noptions string NFS/CIFS mount options (see 'man nfs' or 'man mount.cifs')\npassword string Password for accessing the share/datastore.\npool string Pool.\nport integer 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.\npreallocation string Preallocation mode for raw and qcow2 images. Using 'metadata' on raw images results in preallocation=off. off metadata falloc full\nprune-backups string 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.\nsaferemove boolean Zero-out data when removing LVs.\nsaferemove_throughput string Wipe throughput (cstream -t parameter value).\nsaferemove-stepsize integer Wipe step size in MiB. It will be capped to the maximum supported by the storage. 1 2 4 8 16 32\nserver string Server IP or DNS name.\nshared boolean 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!\nskip-cert-verification boolean Disable TLS certificate verification, only enable on fully trusted networks!\nsmbversion string SMB protocol version. 'default' if not set, negotiates the highest SMB2+ version supported by both the client and server. default 2.0 2.1 3 3.0 3.11\nsnapshot-as-volume-chain boolean Enable support for creating storage-vendor agnostic snapshot through volume backing-chains.\nsparse boolean use sparse volumes\nsubdir string Subdir to mount.\ntagged_only boolean Only list logical volumes tagged with 'pve-vm-ID'.\nusername string RBD Id.\nzfs-base-path string Base path where to look for the created ZFS block devices. Set automatically during creation if not specified. Usually '/dev/zvol'.\ndatastore\nvolume storage\ndatastore\nvolume storage" + }, + { + "id": "GET /version", + "title": "GET /version", + "method": "GET", + "path": "/version", + "section": "version", + "summary": "version", + "searchText": "GET\n/version\nversion\nversion\nAPI version details, including some parts of the global datacenter config." + } +] diff --git a/docs/templates-handoff.md b/docs/templates-handoff.md new file mode 100644 index 00000000000..ccc23da7d5d --- /dev/null +++ b/docs/templates-handoff.md @@ -0,0 +1,64 @@ +# Templates — handoff + +**Status: shelved before build, 2026-08-20.** The template-import feature was +removed from the tree in the commit that rewrote this file; nothing +template-shaped is in flight. This file exists so the revisit does not +re-derive two design rounds. It supersedes `cofoundry-templates-handoff.md` +(deleted the same day; git history has it). + +## Why it was shelved + +PVE 9 can download a **disk image** by URL and attach it to a VM directly +(`import-from` on a disk, `import` content on storages). That beats the whole +vzdump pipeline this feature was built around — download a multi-GB archive +through an agent, `qmrestore` it, `qm template` it, then keep a template +*guest* placed and updated per node/cluster. With images, PVE does the +download itself and there is **no template guest to place**, which dissolves +the VMID-coordination problem that consumed both design rounds. + +Cofoundry currently publishes vzdump archives, so it must be updated to +publish raw disk images (qcow2) first. Revisit after that. + +## Where things stand in the panel + +Exactly the released v4 model, untouched: a `Template` is a name + panel-wide +`vmid` an admin manages by hand, validated live at deploy time +(`ServerCreationService::getTemplate()` checks `template: 1` on the node), and +cloned by `ProxmoxServerClient::create()`. The only template-adjacent thing +that shipped from this effort is the **storage-layer overhaul** (clusters +identified by CA fingerprint, storages one definition per cluster, per-link +capacity — see the `feat(clusters)` commit), which stands on its own and is +what any future "usable from every node that mounts the pool" query will join +against. + +## What was built and thrown away + +- **panel** `feat/templates-cofoundry-import` — registry/catalog/import + services, `template_installs`, polling job, admin endpoints. Rejected model + (one panel-wide VMID fanned out per node). **Gone, not archived:** the branch + was never pushed and was deleted on 2026-09-07, so this paragraph is the only + remaining record of it. Rebuild from the design notes below, not from a diff. +- **anchor** `feat/templates-install` (`7f7b8f4`) — a `templates.install` + capability: download → verify sha256 → `qmrestore` → `qm template`. Sound + for what it did, but PVE 9 image import likely removes the need for an agent + in this feature entirely. Still in the anchor repo on the branch of the same + name, and only for as long as that branch survives. +- The instances redesign (this file's previous revision, plus the removal + commit's parent tree) — `templates`/`template_instances` split, poll-side + reconciliation, CA-scoped placement. Never finished; removed. + +## Ideas worth carrying into the image-based design + +- **Template vs placement stay different facts.** What a user picks vs where + it can deploy from. With images the "placement" may become *which storages + hold the image* — which is exactly a `storage_to_node` join away, already + built. +- **Observed, not typed.** The poll already decodes every guest's `template` + flag from `/cluster/resources`; whatever the new model records should be + verified (and where possible materialized) from observation, not data entry. + Operators hate creating rows for things that already exist. +- **A registry is a catalogue, not a concept.** Cofoundry should stay a + config-default URL; `manual`/`url`/`registry` as a source enum, with + "update available" meaningful only for the latter two. +- **Adoption over forms.** Surface unclaimed observed templates/images and + offer one-click adoption instead of a node+vmid form. diff --git a/docs/v5-next-handoff.md b/docs/v5-next-handoff.md new file mode 100644 index 00000000000..f6931d48a51 --- /dev/null +++ b/docs/v5-next-handoff.md @@ -0,0 +1,1245 @@ +# v5 (`next`) rewrite — working handoff + +Living notes for shipping `next` (v5) as the new trunk. This file tracks *what's done* +(one-line pointers — git history holds the detail) and *what to pick up next*, so a cold start +doesn't re-derive it. Remaining visual-system work is tracked in +[frontend-overhaul-audit.md](frontend-overhaul-audit.md). + +Last updated: 2026-07-15 (session: **Base UI dialog migration + repository layer removed + backups quota + +IPAM mobile rows + live Disks/storage/power/backup verification + collection-state/mobile close-out + +server-create speed-cap verification + application-token network restrictions**). + +## ⚠️ READ FIRST — dialogs/drawers/sheets are now Base UI (`aa5cab9c`, 78 files) + +**`vaul` and `@radix-ui/react-dialog` are UNINSTALLED. `Credenza` is GONE → `ResponsiveDialog`.** +Main JS **378.75 → 359.42 kB** (gzip 115.92 → 109.18). + +**Why (don't undo this):** two bugs existed on every Select-inside-a-dialog, reproduced on `/admin/tokens` — a +screen that session never touched (both token UIs were *build/type-verified only, never clicked*, which is +exactly why they were missed): +1. **Escape closed the whole dialog**, discarding the user's form. +2. **Keyboard nav was dead** — focus never entered the popup, so arrows/typeahead did nothing. Mouse-only. + +One root cause: **Radix Dialog + Base UI Select are two dismissal/focus systems.** Base UI portals its popup +*outside* the dialog, so Radix's focus trap pulls focus back; and both listen for Escape on document in the +**capture** phase, Radix first, whose only cancel lever (`defaultPrevented`) Base UI *also* respects. **No shim +leaves both libraries' handlers intact** — two were tried and both made it worse (one made Escape do nothing). +Migrating removed the whole class of bug with **zero shim code**. Verified: focus enters the popup, ArrowDown +highlights, Escape closes only the select, 2nd Escape closes the dialog. + +- **Drawer:** Base UI ships a **first-party Drawer, stable since 1.3.0** — we were already on 1.6.0 with it + unused. No need to rebuild vaul or use the `vaul-base` community port. This is also where shadcn's own drawer + went ("The drawer component now uses Base UI instead of Vaul"), and their migration guide prescribes the same + `asChild` → `render` swap. +- **`Credenza` → `ResponsiveDialog`** (`components/ui/ResponsiveDialog`). The *concept* was right (it is what + shadcn documents: Dialog desktop / Drawer mobile) but all **eight** parts called `useMediaQuery` — eight + subscriptions to one breakpoint. Now resolved **once** at the root via context; both families being Base UI + means every part is a plain alias with **no adapter**. +- **`asChild` → `render` across 47 files.** Base UI composes via `render`. Prefer `render={ + + + + +${previews.map(section).join('\n')} + +
+
+
+

What changed on the way in

+

Everything else is a straight port.

+
+
+ + + + + +${TRANSLATIONS.map( + ([el, panel, email, why]) => ` + + + + + ` +).join('\n')} + +
ElementPanelEmailWhy
${el}${panel}${ + email.startsWith('#') || email.includes('#') + ? `${email}` + : email + }${why}
+
+
+ +
+
+

Where it lands

+

The light palette is the real design; dark is an improvement where it is honoured.

+
+
+ + + + + +${CLIENTS.map( + ([client, level, gets]) => ` + + + + ` +).join('\n')} + +
ClientSupportGets
${client}${level}${gets}
+
+
+
+ + + +` + +writeFileSync(OUT, page) + +console.log( + `preview: ${previews.length} emails embedded, ${(Buffer.byteLength(page) / 1024).toFixed(0)} KB` +) diff --git a/emails/scripts/build-tokens.mjs b/emails/scripts/build-tokens.mjs new file mode 100644 index 00000000000..d5d8c83afc5 --- /dev/null +++ b/emails/scripts/build-tokens.mjs @@ -0,0 +1,194 @@ +/** + * Generates the email theme from the panel's own tokens. + * + * `resources/scripts/app.css` is the single source of truth for Nova's palette, + * but nothing in it can be handed to an email client as-is: the values are + * OKLCH (unsupported outside WebKit clients), they are referenced through + * `var()` (Gmail strips custom properties), and several are translucent + * (`ring-foreground/10`, `bg-muted/50`), which cannot be relied on to composite + * over a table cell. So the panel's tokens are read, resolved, flattened + * against their known surface, and written out as literal hex. + * + * Run via `npm run tokens` in this directory; the output is committed so a + * plain `maizzle build` never depends on the panel's CSS being present. + */ +import { formatHex, converter, parse } from 'culori' +import { readFileSync, writeFileSync, mkdirSync } from 'node:fs' +import { dirname, resolve } from 'node:path' +import { fileURLToPath } from 'node:url' + +const here = dirname(fileURLToPath(import.meta.url)) +const APP_CSS = resolve(here, '../../resources/scripts/app.css') +const OUT = resolve(here, '../css/tokens.css') + +const toRgb = converter('rgb') + +/** Pull one `:root`-style block's custom properties into a flat map. */ +const readBlock = (css, selector) => { + // The block we want is the first ` {` at the top of a @layer, and + // it contains no nested braces, so a non-greedy match to the first `}` is + // enough — a real CSS parser here would only buy us trouble. + const match = css.match( + new RegExp(`${selector}\\s*\\{([\\s\\S]*?)\\n\\s*\\}`, 'm') + ) + + if (!match) throw new Error(`No ${selector} block in app.css`) + + return Object.fromEntries( + [...match[1].matchAll(/(--[\w-]+)\s*:\s*([^;]+);/g)].map( + ([, name, value]) => [name, value.trim()] + ) + ) +} + +/** `--label: var(--muted-foreground)` — follow the chain to a real colour. */ +const deref = (vars, value, depth = 0) => { + if (depth > 10) throw new Error(`Cyclic var() chain at ${value}`) + + const ref = value.match(/^var\((--[\w-]+)\)$/) + + return ref ? deref(vars, vars[ref[1]], depth + 1) : value +} + +/** + * Flatten alpha against an opaque backdrop. Email gets one composited hex + * instead of a colour that needs the client to blend correctly — Outlook + * renders `rgba()` as fully opaque, so a 10% ring would arrive at 100%. + */ +const over = (fg, bg) => { + const f = toRgb(fg) + const b = toRgb(bg) + const a = f.alpha ?? 1 + + return formatHex({ + mode: 'rgb', + r: f.r * a + b.r * (1 - a), + g: f.g * a + b.g * (1 - a), + b: f.b * a + b.b * (1 - a), + }) +} + +/** Same colour, forced to a given alpha, then composited. */ +const mix = (fg, bg, alpha) => over({ ...toRgb(fg), alpha }, bg) + +const buildTheme = (vars) => { + const get = (name) => { + const raw = vars[name] + + if (!raw) throw new Error(`Missing token ${name}`) + + const parsed = parse(deref(vars, raw)) + + if (!parsed) throw new Error(`Unparseable token ${name}: ${raw}`) + + return parsed + } + + const background = get('--background') + const card = get('--card') + const foreground = get('--foreground') + const muted = get('--muted') + + return { + // Straight ports — every one of these is opaque in app.css. + '--color-background': formatHex(background), + '--color-foreground': formatHex(foreground), + '--color-card': formatHex(card), + '--color-card-foreground': formatHex(get('--card-foreground')), + '--color-muted': formatHex(muted), + '--color-muted-foreground': formatHex(get('--muted-foreground')), + '--color-primary': formatHex(get('--primary')), + '--color-primary-foreground': formatHex(get('--primary-foreground')), + '--color-destructive': formatHex(get('--destructive')), + '--color-success': formatHex(get('--success')), + + // Derived, because the panel expresses these as alpha over a surface + // and email needs the result rather than the recipe. + // + // `--border` is opaque in light mode but `oklch(1 0 0 / 10%)` in dark, + // so it goes through the same compositing path in both — flattening an + // already-opaque colour is a no-op. + '--color-border': over(get('--border'), background), + + // Card.tsx's `ring-1 ring-foreground/10`. Outlook drops box-shadow, so + // this lands as a real 1px border; the colour still has to match. + '--color-card-ring': mix(foreground, card, 0.1), + + // CardFooter.tsx's `bg-muted/50`, over the card rather than the page. + '--color-card-footer': mix(muted, card, 0.5), + + // The page gutter around a 600px email. The panel has no token for it + // (nothing in the app sits outside `--background`), so it is derived + // the same way the app's own surfaces are: one step of foreground into + // the background, which keeps the card reading as raised in both modes. + '--color-canvas': mix(foreground, background, 0.04), + } +} + +const css = readFileSync(APP_CSS, 'utf8') +const light = buildTheme(readBlock(css, ':root')) +const dark = buildTheme(readBlock(css, '\\.dark')) + +const declarations = (theme, indent) => + Object.entries(theme) + .map(([name, value]) => `${indent}${name}: ${value};`) + .join('\n') + +/* + * Dark mode cannot be done the way the panel does it. + * + * In the app, `.dark` swaps the value behind `--card` and every utility follows + * because the utilities reference the variable at runtime. Maizzle resolves + * those variables to literal hex at build time — that resolution is the entire + * reason Nova's OKLCH palette is usable in an inbox at all — so by the time the + * email exists there is no variable left to swap. Redefining `--color-card` + * inside a media query compiles to nothing. + * + * So the dark palette ships as its own set of named tokens and is applied with + * Tailwind's `dark:` variant, which in v4 is already `prefers-color-scheme`. + * Media-query rules cannot be inlined, so juice leaves them in a ` diff --git a/public/index.php b/public/index.php index 5e81d352eff..947d98963f0 100644 --- a/public/index.php +++ b/public/index.php @@ -1,55 +1,17 @@ make(Kernel::class); - -$response = $kernel->handle( - $request = Request::capture() -)->send(); - -$kernel->terminate($request, $response); +// Bootstrap Laravel and handle the request... +(require_once __DIR__.'/../bootstrap/app.php') + ->handleRequest(Request::capture()); diff --git a/resources/pve/qemu-create-schema.json b/resources/pve/qemu-create-schema.json new file mode 100644 index 00000000000..0223ff7a60d --- /dev/null +++ b/resources/pve/qemu-create-schema.json @@ -0,0 +1,70 @@ +{ + "_comment": "Fallback only. A node's own schema, read by Anchor from /usr/share/pve-docs/api-viewer/apidoc.js, always supersedes this -- it is correct for that node's PVE version, and it carries every parameter rather than the handful below. This file exists so a panel with no reachable node can still refuse an obviously wrong profile instead of accepting it and failing at first power-on.", + "parameters": { + "bios": { + "type": "string", + "enum": ["seabios", "ovmf"], + "default": "seabios", + "description": "Select BIOS implementation." + }, + "machine": { + "type": "string", + "description": "Specify the QEMU machine." + }, + "scsihw": { + "type": "string", + "enum": ["lsi", "lsi53c810", "virtio-scsi-pci", "virtio-scsi-single", "megasas", "pvscsi"], + "default": "lsi", + "description": "SCSI controller model." + }, + "ostype": { + "type": "string", + "enum": ["other", "wxp", "w2k", "w2k3", "w2k8", "wvista", "win7", "win8", "win10", "win11", "l24", "l26", "solaris"], + "description": "Specify guest operating system." + }, + "cpu": { + "type": "string", + "description": "Emulated CPU type." + }, + "agent": { + "type": "string", + "description": "Enable/disable communication with the QEMU Guest Agent and its properties." + }, + "vga": { + "type": "string", + "description": "Configure the VGA hardware." + }, + "boot": { + "type": "string", + "description": "Specify guest boot order." + }, + "numa": { + "type": "boolean", + "default": 0, + "description": "Enable/disable NUMA." + }, + "tablet": { + "type": "boolean", + "default": 1, + "description": "Enable/disable the USB tablet device." + }, + "kvm": { + "type": "boolean", + "default": 1, + "description": "Enable/disable KVM hardware virtualization." + }, + "onboot": { + "type": "boolean", + "default": 0, + "description": "Specifies whether a VM will be started during system bootup." + }, + "freeze": { + "type": "boolean", + "description": "Freeze CPU at startup." + }, + "hotplug": { + "type": "string", + "description": "Selectively enable hotplug features." + } + } +} diff --git a/resources/scripts/api/admin/addressPools/addresses/createAddress.ts b/resources/scripts/api/admin/addressPools/addresses/createAddress.ts deleted file mode 100644 index c16b34bed9b..00000000000 --- a/resources/scripts/api/admin/addressPools/addresses/createAddress.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { ipAddress, macAddress } from '@/util/validation' -import { z } from 'zod' - -import { AddressInclude } from '@/api/admin/nodes/addresses/getAddresses' -import http from '@/api/http' -import { Address, rawDataToAddress } from '@/api/server/getServer' - - -const baseSchema = z.object({ - type: z.enum(['ipv4', 'ipv6']), - cidr: z.preprocess(Number, z.number().int().min(1).max(128)), - gateway: ipAddress().nonempty().max(191), - macAddress: macAddress().max(191).nullable().or(z.literal('')), - serverId: z.literal('').or(z.preprocess(Number, z.number())).nullable(), -}) - -const singleAddressSchema = z.object({ - isBulkAction: z.literal(false), - address: ipAddress().nonempty().max(191), -}) - -const multipleAddressesSchema = z.object({ - isBulkAction: z.literal(true), - startingAddress: ipAddress().nonempty().max(191), - endingAddress: ipAddress().nonempty().max(191), -}) - -export const schema = z - .discriminatedUnion('isBulkAction', [ - singleAddressSchema, - multipleAddressesSchema, - ]) - .and(baseSchema) - -type CreateAddressParameters = z.infer & { - startingAddress?: string | null - endingAddress?: string | null - include?: AddressInclude[] -} - -const createAddress = async ( - poolId: number, - { - isBulkAction, - startingAddress, - endingAddress, - macAddress, - serverId, - include, - ...payload - }: CreateAddressParameters -): Promise
=> { - const { - data: { data }, - } = await http.post( - `/api/admin/address-pools/${poolId}/addresses`, - { - is_bulk_action: isBulkAction, - starting_address: startingAddress, - ending_address: endingAddress, - mac_address: macAddress, - server_id: serverId, - ...payload, - }, - { - params: { - include: include?.join(','), - }, - } - ) - - return data ? rawDataToAddress(data) : null -} - -export default createAddress \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/addresses/deleteAddress.ts b/resources/scripts/api/admin/addressPools/addresses/deleteAddress.ts deleted file mode 100644 index 95347af3022..00000000000 --- a/resources/scripts/api/admin/addressPools/addresses/deleteAddress.ts +++ /dev/null @@ -1,6 +0,0 @@ -import http from '@/api/http' - -const deleteAddress = (poolId: number, addressId: number) => - http.delete(`/api/admin/address-pools/${poolId}/addresses/${addressId}`) - -export default deleteAddress \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/addresses/getAddresses.ts b/resources/scripts/api/admin/addressPools/addresses/getAddresses.ts deleted file mode 100644 index b0a7add4467..00000000000 --- a/resources/scripts/api/admin/addressPools/addresses/getAddresses.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - AddressInclude, - AddressResponse, -} from '@/api/admin/nodes/addresses/getAddresses' -import http, { getPaginationSet } from '@/api/http' -import { rawDataToAddress } from '@/api/server/getServer' - -export interface QueryParams { - query?: string - page?: number - perPage?: number - include?: Array -} - -const getAddresses = async ( - addressPoolId: number, - { query, page, perPage = 50, include }: QueryParams -): Promise => { - const { data } = await http.get( - `/api/admin/address-pools/${addressPoolId}/addresses`, - { - params: { - 'filter[*]': query, - page, - 'per_page': perPage, - 'include': include?.join(','), - }, - } - ) - - return { - items: data.data.map(rawDataToAddress), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export default getAddresses \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/addresses/updateAddress.ts b/resources/scripts/api/admin/addressPools/addresses/updateAddress.ts deleted file mode 100644 index 005ebee291a..00000000000 --- a/resources/scripts/api/admin/addressPools/addresses/updateAddress.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { AddressInclude } from '@/api/admin/nodes/addresses/getAddresses' -import http from '@/api/http' -import { AddressType, rawDataToAddress } from '@/api/server/getServer' - -interface UpdateAddressParameters { - address: string - type: AddressType - cidr: number - gateway: string - macAddress: string | null - serverId: number | null - include?: AddressInclude[] -} - -const updateAddress = async ( - poolId: number, - addressId: number, - { macAddress, serverId, include, ...payload }: UpdateAddressParameters -) => { - const { - data: { data }, - } = await http.put( - `/api/admin/address-pools/${poolId}/addresses/${addressId}`, - { - mac_address: macAddress, - server_id: serverId, - ...payload, - }, - { - params: { - include: include?.join(','), - }, - } - ) - - return rawDataToAddress(data) -} - -export default updateAddress \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/createAddressPool.ts b/resources/scripts/api/admin/addressPools/createAddressPool.ts deleted file mode 100644 index a5b28ba1d92..00000000000 --- a/resources/scripts/api/admin/addressPools/createAddressPool.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { rawDataToAddressPool } from '@/api/admin/addressPools/getAddressPools' -import http from '@/api/http' - -interface CreateAddressParameters { - name: string - nodeIds?: number[] | string[] -} - -const createAddressPool = async ({ - name, - nodeIds, -}: CreateAddressParameters) => { - const { - data: { data }, - } = await http.post('/api/admin/address-pools', { - name, - node_ids: nodeIds, - }) - - return rawDataToAddressPool(data) -} - -export default createAddressPool \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/deleteAddressPool.ts b/resources/scripts/api/admin/addressPools/deleteAddressPool.ts deleted file mode 100644 index f2967538f2d..00000000000 --- a/resources/scripts/api/admin/addressPools/deleteAddressPool.ts +++ /dev/null @@ -1,6 +0,0 @@ -import http from '@/api/http' - -const deleteAddressPool = (id: number) => - http.delete(`/api/admin/address-pools/${id}`) - -export default deleteAddressPool \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/getAddressPool.ts b/resources/scripts/api/admin/addressPools/getAddressPool.ts deleted file mode 100644 index df9416473bd..00000000000 --- a/resources/scripts/api/admin/addressPools/getAddressPool.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { rawDataToAddressPool } from '@/api/admin/addressPools/getAddressPools' -import http from '@/api/http' - -const getAddressPool = async (id: number) => { - const { - data: { data }, - } = await http.get(`/api/admin/address-pools/${id}`) - - return rawDataToAddressPool(data) -} - -export default getAddressPool \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/getAddressPools.ts b/resources/scripts/api/admin/addressPools/getAddressPools.ts deleted file mode 100644 index 4896aaedd65..00000000000 --- a/resources/scripts/api/admin/addressPools/getAddressPools.ts +++ /dev/null @@ -1,44 +0,0 @@ -import http, { PaginatedResult, getPaginationSet } from '@/api/http' - -export interface AddressPool { - id: number - name: string - nodesCount: number - addressesCount: number -} - -export interface QueryParams { - query?: string - page?: number - perPage?: number -} - -export type AddressPoolResponse = PaginatedResult - -const getAddressPools = async ({ - query, - page, - perPage = 50, -}: QueryParams): Promise => { - const { data } = await http.get('/api/admin/address-pools', { - params: { - 'filter[*]': query, - page, - 'per_page': perPage, - }, - }) - - return { - items: data.data.map(rawDataToAddressPool), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export const rawDataToAddressPool = (data: any): AddressPool => ({ - id: data.id, - name: data.name, - nodesCount: data.nodes_count, - addressesCount: data.addresses_count, -}) - -export default getAddressPools \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/getAttachedNodes.ts b/resources/scripts/api/admin/addressPools/getAttachedNodes.ts deleted file mode 100644 index 5c0609528ef..00000000000 --- a/resources/scripts/api/admin/addressPools/getAttachedNodes.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { NodeResponse, rawDataToNode } from '@/api/admin/nodes/getNodes' -import http, { getPaginationSet } from '@/api/http' - - -export interface QueryParams { - query?: string | null - fqdn?: string | null - locationId?: number | null - page?: number | null - perPage?: number | null -} - -const getAttachedNodes = async ( - addressPoolId: number, - { query, fqdn, locationId, page, perPage = 50 }: QueryParams -): Promise => { - const { data } = await http.get( - `/api/admin/address-pools/${addressPoolId}/attached-nodes`, - { - params: { - query, - fqdn, - location_id: locationId, - page, - per_page: perPage, - }, - } - ) - - return { - items: data.data.map(rawDataToNode), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export default getAttachedNodes \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/updateAddressPool.ts b/resources/scripts/api/admin/addressPools/updateAddressPool.ts deleted file mode 100644 index 50a42a059ff..00000000000 --- a/resources/scripts/api/admin/addressPools/updateAddressPool.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { rawDataToAddressPool } from '@/api/admin/addressPools/getAddressPools' -import http from '@/api/http' - -interface UpdateAddressPoolParameters { - name: string - nodeIds?: number[] | null -} - -const updateAddressPool = async ( - id: number, - { name, nodeIds }: UpdateAddressPoolParameters -) => { - const { - data: { data }, - } = await http.put(`/api/admin/address-pools/${id}`, { - name, - node_ids: nodeIds, - }) - - return rawDataToAddressPool(data) -} - -export default updateAddressPool diff --git a/resources/scripts/api/admin/addressPools/useAddressPoolNodesSWR.ts b/resources/scripts/api/admin/addressPools/useAddressPoolNodesSWR.ts deleted file mode 100644 index cf908ed7924..00000000000 --- a/resources/scripts/api/admin/addressPools/useAddressPoolNodesSWR.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { useParams } from 'react-router-dom' -import useSWR from 'swr' - -import getAttachedNodes, { - QueryParams, -} from '@/api/admin/addressPools/getAttachedNodes' -import { NodeResponse } from '@/api/admin/nodes/getNodes' - -const useAddressPoolNodesSWR = ( - poolId: number, - { page, query, ...params }: QueryParams -) => { - return useSWR( - ['admin.address-pools.nodes', poolId, page, query], - () => - getAttachedNodes(poolId, { - page, - query, - ...params, - }) - ) -} - -export default useAddressPoolNodesSWR diff --git a/resources/scripts/api/admin/addressPools/useAddressPoolSWR.ts b/resources/scripts/api/admin/addressPools/useAddressPoolSWR.ts deleted file mode 100644 index ad475d485f0..00000000000 --- a/resources/scripts/api/admin/addressPools/useAddressPoolSWR.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Optimistic } from '@/lib/swr' -import { useMatch } from 'react-router-dom' -import useSWR, { Key, SWRResponse } from 'swr' - -import getAddressPool from '@/api/admin/addressPools/getAddressPool' -import { AddressPool } from '@/api/admin/addressPools/getAddressPools' - - -export const getKey = (id: number): Key => ['admin.address-pools', id] - -const useAddressPoolSWR = () => { - const match = useMatch('/admin/ipam/:id/*') - const id = parseInt(match!.params.id!) - - return useSWR(getKey(id), () => getAddressPool(id), { - revalidateOnMount: false, - }) as Optimistic> -} - -export default useAddressPoolSWR \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/useAddressPoolsSWR.ts b/resources/scripts/api/admin/addressPools/useAddressPoolsSWR.ts deleted file mode 100644 index 8148f58c4cf..00000000000 --- a/resources/scripts/api/admin/addressPools/useAddressPoolsSWR.ts +++ /dev/null @@ -1,20 +0,0 @@ -import useSWR from 'swr' - -import getAddressPools, { - AddressPoolResponse, - QueryParams, -} from '@/api/admin/addressPools/getAddressPools' - -const useAddressPoolsSWR = ({ page, query, ...params }: QueryParams) => { - return useSWR( - ['admin.address-pools', page, query], - () => - getAddressPools({ - page, - query, - ...params, - }) - ) -} - -export default useAddressPoolsSWR \ No newline at end of file diff --git a/resources/scripts/api/admin/addressPools/useAddressesSWR.ts b/resources/scripts/api/admin/addressPools/useAddressesSWR.ts deleted file mode 100644 index 1fb8f6d977a..00000000000 --- a/resources/scripts/api/admin/addressPools/useAddressesSWR.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Optimistic } from '@/lib/swr' -import { useMatch } from 'react-router-dom' -import useSWR, { Key, SWRResponse } from 'swr' - -import getAddresses, { - QueryParams, -} from '@/api/admin/addressPools/addresses/getAddresses' -import { AddressResponse } from '@/api/admin/nodes/addresses/getAddresses' - -export const getKey = (id: number, page?: number, query?: string): Key => [ - 'admin.address-pools.addresses', - id, - page, - query, -] - -const useAddressesSWR = ({ page, query, ...params }: QueryParams) => { - const match = useMatch('/admin/ipam/:id/*') - const id = parseInt(match!.params.id!) - - return useSWR( - getKey(id, page, query), - () => - getAddresses(id, { - page, - query, - ...params, - }), - { - revalidateOnMount: false, - } - ) as Optimistic> -} - -export default useAddressesSWR diff --git a/resources/scripts/api/admin/coterms/createCoterm.ts b/resources/scripts/api/admin/coterms/createCoterm.ts deleted file mode 100644 index be91c04c954..00000000000 --- a/resources/scripts/api/admin/coterms/createCoterm.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { rawDataToCoterm } from '@/api/admin/coterms/getCoterms' -import http from '@/api/http' - -interface CreateCotermParameters { - name: string - isTlsEnabled: boolean - fqdn: string - port: number - nodeIds?: number[] | null -} - -const createCoterm = async ({ - name, - isTlsEnabled, - fqdn, - port, - nodeIds, -}: CreateCotermParameters) => { - const { - data: { data }, - } = await http.post('/api/admin/coterms', { - name, - is_tls_enabled: isTlsEnabled, - fqdn, - port, - node_ids: nodeIds, - }) - - return rawDataToCoterm(data) -} - -export default createCoterm \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/deleteCoterm.ts b/resources/scripts/api/admin/coterms/deleteCoterm.ts deleted file mode 100644 index 3846335d8ad..00000000000 --- a/resources/scripts/api/admin/coterms/deleteCoterm.ts +++ /dev/null @@ -1,5 +0,0 @@ -import http from '@/api/http' - -const deleteCoterm = (id: string) => http.delete(`/api/admin/coterms/${id}`) - -export default deleteCoterm \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/getAttachedNodes.ts b/resources/scripts/api/admin/coterms/getAttachedNodes.ts deleted file mode 100644 index d4649682e20..00000000000 --- a/resources/scripts/api/admin/coterms/getAttachedNodes.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { NodeResponse, rawDataToNode } from '@/api/admin/nodes/getNodes' -import http, { getPaginationSet } from '@/api/http' - - -export interface QueryParams { - query?: string | null - fqdn?: string | null - locationId?: number | null - page?: number | null - perPage?: number | null -} - -const getAttachedNodes = async ( - id: number, - { query, fqdn, locationId, page, perPage = 50 }: QueryParams -): Promise => { - const { data } = await http.get(`/api/admin/coterms/${id}/nodes`, { - params: { - query, - fqdn, - location_id: locationId, - page, - per_page: perPage, - }, - }) - - return { - items: data.data.map(rawDataToNode), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export default getAttachedNodes \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/getCoterm.ts b/resources/scripts/api/admin/coterms/getCoterm.ts deleted file mode 100644 index 673c173f049..00000000000 --- a/resources/scripts/api/admin/coterms/getCoterm.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { rawDataToCoterm } from '@/api/admin/coterms/getCoterms' -import http from '@/api/http' - - -const getCoterm = async (id: number) => { - const { - data: { data }, - } = await http.get(`/api/admin/coterms/${id}`) - - return rawDataToCoterm(data) -} - -export default getCoterm \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/getCoterms.ts b/resources/scripts/api/admin/coterms/getCoterms.ts deleted file mode 100644 index 1d46e38b6ff..00000000000 --- a/resources/scripts/api/admin/coterms/getCoterms.ts +++ /dev/null @@ -1,52 +0,0 @@ -import http, { PaginatedResult, getPaginationSet } from '@/api/http' - -export interface Coterm { - id: number - name: string - isTlsEnabled: boolean - fqdn: string - port: number - nodesCount: number - tokenId?: string - token?: string -} - -export type CotermResponse = PaginatedResult - -export interface QueryParams { - query?: string - page?: number - perPage?: number -} - -const getCoterms = async ({ - query, - page, - perPage = 50, -}: QueryParams): Promise => { - const { data } = await http.get('/api/admin/coterms', { - params: { - 'filter[*]': query, - page, - 'per_page': perPage, - }, - }) - - return { - items: data.data.map(rawDataToCoterm), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export const rawDataToCoterm = (data: any): Coterm => ({ - id: data.id, - name: data.name, - isTlsEnabled: Boolean(data.is_tls_enabled), - fqdn: data.fqdn, - port: data.port, - nodesCount: data.nodes_count, - tokenId: data.token_id, - token: data.token, -}) - -export default getCoterms \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/resetCotermToken.ts b/resources/scripts/api/admin/coterms/resetCotermToken.ts deleted file mode 100644 index 0cbd4a5cbc2..00000000000 --- a/resources/scripts/api/admin/coterms/resetCotermToken.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { rawDataToCoterm } from '@/api/admin/coterms/getCoterms' -import http from '@/api/http' - - -const resetCotermToken = async (id: number) => { - const { - data: { data }, - } = await http.post(`/api/admin/coterms/${id}/reset-coterm-token`) - - return rawDataToCoterm(data) -} - -export default resetCotermToken \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/updateAttachedNodes.ts b/resources/scripts/api/admin/coterms/updateAttachedNodes.ts deleted file mode 100644 index a0693c2553b..00000000000 --- a/resources/scripts/api/admin/coterms/updateAttachedNodes.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { rawDataToCoterm } from '@/api/admin/coterms/getCoterms' -import http from '@/api/http' - - -const updateAttachedNodes = async (id: number, nodeIds: number[]) => { - const { - data: { data }, - } = await http.put(`/api/admin/coterms/${id}/nodes`, { - node_ids: nodeIds, - }) - - return rawDataToCoterm(data) -} - -export default updateAttachedNodes \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/updateCoterm.ts b/resources/scripts/api/admin/coterms/updateCoterm.ts deleted file mode 100644 index e0ad6f52915..00000000000 --- a/resources/scripts/api/admin/coterms/updateCoterm.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { rawDataToCoterm } from '@/api/admin/coterms/getCoterms' -import http from '@/api/http' - -interface UpdateCotermParameters { - name: string - isTlsEnabled: boolean - fqdn: string - port: number - nodeIds?: number[] | null -} - -const updateCoterm = async ( - id: number, - { name, isTlsEnabled, fqdn, port, nodeIds }: UpdateCotermParameters -) => { - const { - data: { data }, - } = await http.put(`/api/admin/coterms/${id}`, { - name, - is_tls_enabled: isTlsEnabled, - fqdn, - port, - node_ids: nodeIds, - }) - - return rawDataToCoterm(data) -} - -export default updateCoterm \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/useAttachedNodes.ts b/resources/scripts/api/admin/coterms/useAttachedNodes.ts deleted file mode 100644 index 4c1ac33bae9..00000000000 --- a/resources/scripts/api/admin/coterms/useAttachedNodes.ts +++ /dev/null @@ -1,21 +0,0 @@ -import useSWR from 'swr' - -import getAttachedNodes, { - QueryParams, -} from '@/api/admin/coterms/getAttachedNodes' - - -const useAttachedNodes = ( - id: number, - { page, query, ...params }: QueryParams -) => { - return useSWR(['admin.coterms.attachedNodes', id, page, query], () => - getAttachedNodes(id, { - page, - query, - ...params, - }) - ) -} - -export default useAttachedNodes \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/useCotermSWR.ts b/resources/scripts/api/admin/coterms/useCotermSWR.ts deleted file mode 100644 index 93e0a9c4701..00000000000 --- a/resources/scripts/api/admin/coterms/useCotermSWR.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Optimistic } from '@/lib/swr' -import { useParams } from 'react-router-dom' -import useSWR, { Key, SWRResponse } from 'swr' - -import getCoterm from '@/api/admin/coterms/getCoterm' -import { Coterm } from '@/api/admin/coterms/getCoterms' - - -export const getKey = (id: number): Key => ['admin.coterms', id] - -const useCotermSWR = () => { - const { cotermId } = useParams() - const id = parseInt(cotermId!) - - return useSWR(getKey(id), () => getCoterm(id), { - revalidateOnMount: false, - }) as Optimistic> -} - -export default useCotermSWR \ No newline at end of file diff --git a/resources/scripts/api/admin/coterms/useCotermsSWR.ts b/resources/scripts/api/admin/coterms/useCotermsSWR.ts deleted file mode 100644 index 0ecdb96317e..00000000000 --- a/resources/scripts/api/admin/coterms/useCotermsSWR.ts +++ /dev/null @@ -1,12 +0,0 @@ -import useSWR from 'swr' - - - -import getCoterms, { CotermResponse, QueryParams } from "@/api/admin/coterms/getCoterms"; - - -const useCotermsSWR = ({ page, query, ...params }: QueryParams) => { - return useSWR(['admin.coterms', page, query], () => getCoterms({ page, query, ...params })) -} - -export default useCotermsSWR \ No newline at end of file diff --git a/resources/scripts/api/admin/locations/createLocation.ts b/resources/scripts/api/admin/locations/createLocation.ts deleted file mode 100644 index 936fc309b3e..00000000000 --- a/resources/scripts/api/admin/locations/createLocation.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Location, rawDataToLocation } from '@/api/admin/locations/getLocations' -import http from '@/api/http' - -export default async ( - shortCode: string, - description: string | null -): Promise => { - const { - data: { data }, - } = await http.post('/api/admin/locations', { - short_code: shortCode, - description, - }) - - return rawDataToLocation(data) -} \ No newline at end of file diff --git a/resources/scripts/api/admin/locations/deleteLocation.ts b/resources/scripts/api/admin/locations/deleteLocation.ts deleted file mode 100644 index 2021018a440..00000000000 --- a/resources/scripts/api/admin/locations/deleteLocation.ts +++ /dev/null @@ -1,3 +0,0 @@ -import http from '@/api/http' - -export default (id: number) => http.delete(`/api/admin/locations/${id}`) \ No newline at end of file diff --git a/resources/scripts/api/admin/locations/getLocations.ts b/resources/scripts/api/admin/locations/getLocations.ts deleted file mode 100644 index 99c4c7849c5..00000000000 --- a/resources/scripts/api/admin/locations/getLocations.ts +++ /dev/null @@ -1,54 +0,0 @@ -import http, { - FractalResponseData, - PaginatedResult, - getPaginationSet, -} from '@/api/http' - -export interface Location { - id: number - shortCode: string - description: string | null - nodesCount: number - serversCount: number -} - -export const rawDataToLocation = (data: FractalResponseData): Location => ({ - id: data.id, - shortCode: data.short_code, - description: data.description, - nodesCount: data.nodes_count, - serversCount: data.servers_count, -}) - -export interface QueryParams { - query?: string - page?: number - perPage?: number -} - -export type LocationResponse = PaginatedResult - -export default ({ - query, - perPage = 50, - ...params -}: QueryParams): Promise> => { - return new Promise((resolve, reject) => { - http.get('/api/admin/locations', { - params: { - 'filter[*]': query, - 'per_page': perPage, - ...params, - }, - }) - .then(({ data }) => - resolve({ - items: (data.data || []).map((datum: any) => - rawDataToLocation(datum) - ), - pagination: getPaginationSet(data.meta.pagination), - }) - ) - .catch(reject) - }) -} \ No newline at end of file diff --git a/resources/scripts/api/admin/locations/updateLocation.ts b/resources/scripts/api/admin/locations/updateLocation.ts deleted file mode 100644 index b5046146b5f..00000000000 --- a/resources/scripts/api/admin/locations/updateLocation.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Location, rawDataToLocation } from '@/api/admin/locations/getLocations' -import http from '@/api/http' - -const updateLocation = async ( - id: number, - shortCode: string, - description: string | null -): Promise => { - const { - data: { data }, - } = await http.put(`/api/admin/locations/${id}`, { - short_code: shortCode, - description, - }) - - return rawDataToLocation(data) -} - -export default updateLocation \ No newline at end of file diff --git a/resources/scripts/api/admin/locations/useLocationsSWR.ts b/resources/scripts/api/admin/locations/useLocationsSWR.ts deleted file mode 100644 index 3b671bfe838..00000000000 --- a/resources/scripts/api/admin/locations/useLocationsSWR.ts +++ /dev/null @@ -1,14 +0,0 @@ -import useSWR from 'swr' - -import getLocations, { - LocationResponse, - QueryParams, -} from '@/api/admin/locations/getLocations' - -const useLocationsSWR = ({ page, query, ...params }: QueryParams) => { - return useSWR(['admin:locations', page, query], () => - getLocations({ page, query, ...params }) - ) -} - -export default useLocationsSWR \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/addresses/createAddress.ts b/resources/scripts/api/admin/nodes/addresses/createAddress.ts deleted file mode 100644 index b768b19a9de..00000000000 --- a/resources/scripts/api/admin/nodes/addresses/createAddress.ts +++ /dev/null @@ -1,31 +0,0 @@ -import http from '@/api/http' -import { Address, AddressType, rawDataToAddress } from '@/api/server/getServer' - -export interface AddressParameters { - serverId?: number - address: string - cidr: number - gateway: string - macAddress?: string - type: AddressType -} - -const createAddress = async ( - nodeId: number, - payload: AddressParameters -): Promise
=> { - const { - data: { data }, - } = await http.post(`/api/admin/nodes/${nodeId}/addresses`, { - server_id: payload.serverId, - address: payload.address, - cidr: payload.cidr, - gateway: payload.gateway, - mac_address: payload.macAddress, - type: payload.type, - }) - - return rawDataToAddress(data) -} - -export default createAddress \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/addresses/getAddresses.ts b/resources/scripts/api/admin/nodes/addresses/getAddresses.ts deleted file mode 100644 index e6bb06537e0..00000000000 --- a/resources/scripts/api/admin/nodes/addresses/getAddresses.ts +++ /dev/null @@ -1,48 +0,0 @@ -import http, { PaginatedResult, getPaginationSet } from '@/api/http' -import { Address, AddressType, rawDataToAddress } from '@/api/server/getServer' - -export type AddressInclude = 'server' - -export type AddressResponse = PaginatedResult
- -export interface QueryParams { - serverId?: number | null - type?: AddressType - address?: string - query?: string - page?: number - perPage?: number - include?: Array -} - -const getAddresses = async ( - nodeId: number, - { - serverId, - type, - address, - query, - perPage = 50, - include, - ...params - }: QueryParams -): Promise => { - const { data } = await http.get(`/api/admin/nodes/${nodeId}/addresses`, { - params: { - 'filter[server_id]': serverId === null ? '' : serverId, - 'filter[type]': type, - 'filter[address]': address, - 'filter[*]': query, - 'per_page': perPage, - 'include': include?.join(','), - ...params, - }, - }) - - return { - items: data.data.map(rawDataToAddress), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export default getAddresses \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/addresses/updateAddress.ts b/resources/scripts/api/admin/nodes/addresses/updateAddress.ts deleted file mode 100644 index 5d4c2e1385b..00000000000 --- a/resources/scripts/api/admin/nodes/addresses/updateAddress.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { AddressParameters } from '@/api/admin/nodes/addresses/createAddress' -import http from '@/api/http' -import { Address, rawDataToAddress } from '@/api/server/getServer' - -const updateAddress = async ( - nodeId: number, - addressId: number, - payload: AddressParameters -): Promise
=> { - const { - data: { data }, - } = await http.put(`/api/admin/nodes/${nodeId}/addresses/${addressId}`, { - server_id: payload.serverId, - address: payload.address, - cidr: payload.cidr, - gateway: payload.gateway, - mac_address: payload.macAddress, - type: payload.type, - }) - - return rawDataToAddress(data) -} - -export default updateAddress \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/addresses/useAddressesSWR.ts b/resources/scripts/api/admin/nodes/addresses/useAddressesSWR.ts deleted file mode 100644 index 9a7748d6b90..00000000000 --- a/resources/scripts/api/admin/nodes/addresses/useAddressesSWR.ts +++ /dev/null @@ -1,19 +0,0 @@ -import useSWR from 'swr' - -import getAddresses, { - AddressResponse, - QueryParams, -} from '@/api/admin/nodes/addresses/getAddresses' - -interface Params extends QueryParams { - id?: string | number -} - -const useAddressesSWR = (nodeId: number, { page, id, ...params }: Params) => { - return useSWR( - ['admin:node:addresses', nodeId, page, id], - () => getAddresses(nodeId, { page, ...params }) - ) -} - -export default useAddressesSWR \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/createNode.ts b/resources/scripts/api/admin/nodes/createNode.ts deleted file mode 100644 index d77eb847276..00000000000 --- a/resources/scripts/api/admin/nodes/createNode.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Node, rawDataToNode } from '@/api/admin/nodes/getNodes' -import http from '@/api/http' - -interface CreateNodeParameters { - locationId: number - name: string - cluster: string - verifyTls: boolean - fqdn: string - tokenId: string - secret: string - port: number - memory: number - memoryOverallocate: number - disk: number - diskOverallocate: number - vmStorage: string - backupStorage: string - isoStorage: string - network: string -} - -const createNode = async (data: CreateNodeParameters): Promise => { - const { - data: { data: responseData }, - } = await http.post('/api/admin/nodes', { - location_id: data.locationId, - name: data.name, - cluster: data.cluster, - verify_tls: data.verifyTls, - fqdn: data.fqdn, - token_id: data.tokenId, - secret: data.secret, - port: data.port, - memory: data.memory, - memory_overallocate: data.memoryOverallocate, - disk: data.disk, - disk_overallocate: data.diskOverallocate, - vm_storage: data.vmStorage, - backup_storage: data.backupStorage, - iso_storage: data.isoStorage, - network: data.network, - }) - - return rawDataToNode(responseData) -} - -export default createNode diff --git a/resources/scripts/api/admin/nodes/deleteNode.ts b/resources/scripts/api/admin/nodes/deleteNode.ts deleted file mode 100644 index 233b49d8aa5..00000000000 --- a/resources/scripts/api/admin/nodes/deleteNode.ts +++ /dev/null @@ -1,5 +0,0 @@ -import http from '@/api/http' - -const deleteNode = (id: number) => http.delete(`/api/admin/nodes/${id}`) - -export default deleteNode \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/getNode.ts b/resources/scripts/api/admin/nodes/getNode.ts deleted file mode 100644 index 1dd95247deb..00000000000 --- a/resources/scripts/api/admin/nodes/getNode.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Node, rawDataToNode } from '@/api/admin/nodes/getNodes' -import http from '@/api/http' - -const getNode = async (id: number): Promise => { - const { - data: { data }, - } = await http.get(`/api/admin/nodes/${id}`) - - return rawDataToNode(data) -} - -export default getNode \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/getNodes.ts b/resources/scripts/api/admin/nodes/getNodes.ts deleted file mode 100644 index 82ce1277520..00000000000 --- a/resources/scripts/api/admin/nodes/getNodes.ts +++ /dev/null @@ -1,83 +0,0 @@ -import http, { PaginatedResult, getPaginationSet } from '@/api/http' - -export interface Node { - id: number - locationId: number - name: string - cluster: string - verifyTls: boolean - fqdn: string - port: number - memory: number - memoryOverallocate: number - memoryAllocated: number - disk: number - diskOverallocate: number - diskAllocated: number - vmStorage: string - backupStorage: string - isoStorage: string - network: string - cotermId: number | null - serversCount: number -} - -export const rawDataToNode = (data: any): Node => ({ - id: data.id, - locationId: data.location_id, - name: data.name, - cluster: data.cluster, - verifyTls: data.verify_tls, - fqdn: data.fqdn, - port: data.port, - memory: data.memory, - memoryOverallocate: data.memory_overallocate, - memoryAllocated: data.memory_allocated, - disk: data.disk, - diskOverallocate: data.disk_overallocate, - diskAllocated: data.disk_allocated, - vmStorage: data.vm_storage, - backupStorage: data.backup_storage, - isoStorage: data.iso_storage, - network: data.network, - cotermId: data.coterm_id, - serversCount: data.servers_count, -}) - -export type NodeResponse = PaginatedResult - -export interface QueryParams { - query?: string | null - cotermId?: number | null - id?: number | number[] | string | string[] - page?: number - perPage?: number -} - -const getNodes = async ({ - query, - cotermId, - id, - perPage = 50, - ...params -}: QueryParams): Promise => { - const { data } = await http.get('/api/admin/nodes', { - params: { - 'filter[*]': query, - 'filter[coterm_id]': cotermId === null ? '' : cotermId, - 'filter[id]': id - ? Array.isArray(id) - ? id.join(',') - : id - : undefined, - ...params, - }, - }) - - return { - items: (data.data || []).map((datum: any) => rawDataToNode(datum)), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export default getNodes diff --git a/resources/scripts/api/admin/nodes/isos/createIso.ts b/resources/scripts/api/admin/nodes/isos/createIso.ts deleted file mode 100644 index 5c1a563c81c..00000000000 --- a/resources/scripts/api/admin/nodes/isos/createIso.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ISO, rawDataToISO } from '@/api/admin/nodes/isos/getIsos' -import http from '@/api/http' - -export type ChecksumAlgorithm = - | 'md5' - | 'sha1' - | 'sha224' - | 'sha256' - | 'sha384' - | 'sha512' - -interface CreateIsoParameters { - shouldDownload: boolean - name: string - fileName: string - hidden: boolean - link?: string - checksumAlgorithm?: ChecksumAlgorithm - checksum?: string -} - -const createIso = async ( - nodeId: number, - { - shouldDownload, - fileName, - checksumAlgorithm, - checksum, - ...data - }: CreateIsoParameters -): Promise => { - const { - data: { data: responseData }, - } = await http.post(`/api/admin/nodes/${nodeId}/isos`, { - should_download: shouldDownload, - file_name: fileName, - checksum_algorithm: checksumAlgorithm, - checksum: checksumAlgorithm ? checksum : undefined, - ...data, - }) - - return rawDataToISO(responseData) -} - -export default createIso \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/isos/deleteIso.ts b/resources/scripts/api/admin/nodes/isos/deleteIso.ts deleted file mode 100644 index 03d71f760ed..00000000000 --- a/resources/scripts/api/admin/nodes/isos/deleteIso.ts +++ /dev/null @@ -1,6 +0,0 @@ -import http from '@/api/http' - -const deleteIso = (nodeId: number, isoUuid: string) => - http.delete(`/api/admin/nodes/${nodeId}/isos/${isoUuid}`) - -export default deleteIso \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/isos/getIsos.ts b/resources/scripts/api/admin/nodes/isos/getIsos.ts deleted file mode 100644 index 2816c8e8397..00000000000 --- a/resources/scripts/api/admin/nodes/isos/getIsos.ts +++ /dev/null @@ -1,56 +0,0 @@ -import http, { PaginatedResult, getPaginationSet } from '@/api/http' - -export interface ISO { - uuid: string - isSuccessful: boolean - name: string - fileName: string - size: number - hidden: boolean - completedAt?: Date - createdAt: Date -} - -export const rawDataToISO = (rawData: any): ISO => ({ - uuid: rawData.uuid, - isSuccessful: rawData.is_successful, - name: rawData.name, - fileName: rawData.file_name, - size: rawData.size, - hidden: Boolean(rawData.hidden), - completedAt: rawData.completed_at - ? new Date(rawData.completed_at) - : undefined, - createdAt: new Date(rawData.created_at), -}) - -export interface QueryParams { - nodeId: number - query?: string - page?: number - perPage?: number -} - -export type IsoResponse = PaginatedResult - -const getIsos = async ({ - nodeId, - query, - perPage = 50, - ...params -}: QueryParams): Promise => { - const { data } = await http.get(`/api/admin/nodes/${nodeId}/isos`, { - params: { - 'filter[name]': query, - 'per_page': perPage, - ...params, - }, - }) - - return { - items: data.data.map(rawDataToISO), - pagination: getPaginationSet(data.meta.pagination), - } -} - -export default getIsos \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/isos/updateIso.ts b/resources/scripts/api/admin/nodes/isos/updateIso.ts deleted file mode 100644 index e30b557813d..00000000000 --- a/resources/scripts/api/admin/nodes/isos/updateIso.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ISO, rawDataToISO } from '@/api/admin/nodes/isos/getIsos' -import http from '@/api/http' - -const updateIso = async ( - nodeId: number, - isoUuid: string, - name: string, - hidden: boolean -): Promise => { - const { - data: { data }, - } = await http.put(`/api/admin/nodes/${nodeId}/isos/${isoUuid}`, { - name, - hidden, - }) - - return rawDataToISO(data) -} - -export default updateIso \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/isos/useIsosSWR.ts b/resources/scripts/api/admin/nodes/isos/useIsosSWR.ts deleted file mode 100644 index 46cd9486e58..00000000000 --- a/resources/scripts/api/admin/nodes/isos/useIsosSWR.ts +++ /dev/null @@ -1,14 +0,0 @@ -import useSWR from 'swr' - -import getIsos, { - IsoResponse, - QueryParams, -} from '@/api/admin/nodes/isos/getIsos' - -const useIsosSWR = ({ page, nodeId, ...params }: QueryParams) => { - return useSWR(['admin:node:isos', nodeId, page], () => - getIsos({ page, nodeId, ...params }) - ) -} - -export default useIsosSWR \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/templateGroups/createTemplateGroup.ts b/resources/scripts/api/admin/nodes/templateGroups/createTemplateGroup.ts deleted file mode 100644 index 345155f7477..00000000000 --- a/resources/scripts/api/admin/nodes/templateGroups/createTemplateGroup.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - TemplateGroup, - rawDataToTemplateGroup, -} from '@/api/admin/nodes/templateGroups/getTemplateGroups' -import http from '@/api/http' - -export interface TemplateGroupParameters { - name: string - hidden: boolean -} - -const createTemplateGroup = async ( - nodeId: number, - parameters: TemplateGroupParameters -): Promise => { - const { - data: { data }, - } = await http.post( - `/api/admin/nodes/${nodeId}/template-groups`, - parameters - ) - - return rawDataToTemplateGroup(data) -} - -export default createTemplateGroup \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/templateGroups/deleteTemplateGroup.ts b/resources/scripts/api/admin/nodes/templateGroups/deleteTemplateGroup.ts deleted file mode 100644 index 3af1508c6c0..00000000000 --- a/resources/scripts/api/admin/nodes/templateGroups/deleteTemplateGroup.ts +++ /dev/null @@ -1,6 +0,0 @@ -import http from '@/api/http' - -const deleteTemplateGroup = (nodeId: number, groupUuid: string) => - http.delete(`/api/admin/nodes/${nodeId}/template-groups/${groupUuid}`) - -export default deleteTemplateGroup \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/templateGroups/getTemplateGroups.ts b/resources/scripts/api/admin/nodes/templateGroups/getTemplateGroups.ts deleted file mode 100644 index 0ddeed10f8a..00000000000 --- a/resources/scripts/api/admin/nodes/templateGroups/getTemplateGroups.ts +++ /dev/null @@ -1,51 +0,0 @@ -import http from '@/api/http' - -export interface TemplateGroup { - id: number - nodeId: number - uuid: string - name: string - hidden: boolean - templates?: Template[] - orderColumn: number -} - -export interface Template { - id: number - templateGroupId: number - uuid: string - name: string - vmid: number - hidden: boolean - orderColumn: number -} - -export const rawDataToTemplateGroup = (data: any): TemplateGroup => ({ - id: data.id, - nodeId: data.node_id, - uuid: data.uuid, - name: data.name, - hidden: Boolean(data.hidden), - templates: data?.templates?.data.map(rawDataToTemplate), - orderColumn: data.order_column, -}) - -export const rawDataToTemplate = (data: any): Template => ({ - id: data.id, - templateGroupId: data.template_group_id, - uuid: data.uuid, - name: data.name, - vmid: data.vmid, - hidden: Boolean(data.hidden), - orderColumn: data.order_column, -}) - -const getTemplateGroups = async (nodeId: number): Promise => { - const { - data: { data }, - } = await http.get(`/api/admin/nodes/${nodeId}/template-groups`) - - return data.map(rawDataToTemplateGroup) -} - -export default getTemplateGroups \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/templateGroups/reorderTemplateGroups.ts b/resources/scripts/api/admin/nodes/templateGroups/reorderTemplateGroups.ts deleted file mode 100644 index 417b8b3b319..00000000000 --- a/resources/scripts/api/admin/nodes/templateGroups/reorderTemplateGroups.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - TemplateGroup, - rawDataToTemplateGroup, -} from '@/api/admin/nodes/templateGroups/getTemplateGroups' -import http from '@/api/http' - -const reorderTemplateGroups = async ( - nodeId: number, - groups: number[] -): Promise => { - const { - data: { data }, - } = await http.post(`/api/admin/nodes/${nodeId}/template-groups/reorder`, { - order: groups, - }) - - return data.map(rawDataToTemplateGroup) -} - -export default reorderTemplateGroups \ No newline at end of file diff --git a/resources/scripts/api/admin/nodes/templateGroups/templates/createTemplate.ts b/resources/scripts/api/admin/nodes/templateGroups/templates/createTemplate.ts deleted file mode 100644 index b3f93d7c1c1..00000000000 --- a/resources/scripts/api/admin/nodes/templateGroups/templates/createTemplate.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - Template, - rawDataToTemplate, -} from '@/api/admin/nodes/templateGroups/getTemplateGroups' -import http from '@/api/http' - -export interface TemplateParameters { - name: string - vmid: number - hidden: boolean -} - -const createTemplate = async ( - nodeId: number, - groupUuid: string, - parameters: TemplateParameters -): Promise